A question of logic/architecture

48 views
Skip to first unread message

Luke Rhodes

unread,
Mar 28, 2015, 10:41:19 PM3/28/15
to fireba...@googlegroups.com
Hi,

We'd like to show our users a list of events sorted by date.

Each user may be sent different events and so each users stores their own index of event uid's with a priority to to that of the event date. There may be hundreds of events and we'll be wanting to list them in batches, incrementally.

We may additionally want to sort by other things like location...for that we would either look to store multiple values in the index or have multiple indexes  for the different items we with to sort by.

So far so good, when an event is created - it gets added to each relevant users index of events.

But...what if I want to change the event date? I would have to update every single users index with a new priority which would be extremely slow.

I'd really appreciate some insight on how you'd solve this problem with Firebase.

Thanks!

Luke

visdyn

unread,
Mar 29, 2015, 8:46:48 AM3/29/15
to fireba...@googlegroups.com
Much of the answer would be dependent on what the perspective is:

Does the event coordinator need to know what users are attending?
Do the users need to know all of the events they are signed up for?

So your current Firebase structure is conceptually something like this:

Events_Node
   
Event1:event_date
   
Event2:event_date
   
Event3:event_date

Users_Node
   
User1
     
Events_To_Attend
       
Event1
       
Event3
   
User2
     
Events_To_Attend
       
Event2
       
Event3


Without knowing some of the other dynamics of your project, it's hard to provide a specific answer. However, the simplest solution would be that each user observe the Events_Node  (FEEventChildChanged) and if the event that changes is one that is listed in the users Events_To_Attend node then take appropriate action.

That could be further drilled down and each user could just observe the event they signed up for instead of the entire Events_To_Attend node.

Optionally, the structure could be changed to this:

Events_Node
   
Event1:event_date
       
Attending_Users
           
User1
           
User3
User_Node
   
User1
   
User2
   
User3


When Event1 date is changed, there's a built in list of attending users so they could be notified of the change.

Heck - you could go crazy and add a very flat third node that has a list of events and users and run a query against that, retrieving the event and users that are affected by the event date change, then after all the users are notified and the Users_Node updated, delete the children in the Events_That_Got_Updated node.

Events_That_Got_Updated
   
Event1:User2
   
Event2:User3
Message has been deleted

visdyn

unread,
Mar 29, 2015, 9:06:14 AM3/29/15
to fireba...@googlegroups.com
Edit: in the section where I mentioned drilling down, the post should say:

observe the event they signed up for instead of the entire Events_Node  (not Events_To_Attend)

i.e.  User1 and User 3 would observe event1... User1 and User2 would observe Event2 etc.

Sure would be nice if posts could be edited.

Luke Rhodes

unread,
Mar 29, 2015, 7:33:16 PM3/29/15
to fireba...@googlegroups.com
Hey, thanks for your responses, they've helped me to come up with a solution that might work but still hopeful for a better one.

Some more details:

Imagine it's an entire event/meetup solution with the ability to sort by date of event, namu, and  creation time of the event. We'll be implementing sorting by distance from you but that'll be using Firbase geo examples.

Events also have attendees and which users will see the event in their list (we determine whether the event is likely to be suited to you and show it only if it is)

The structure looks similar to the following:


We store the data belonging to the event in a single place:

/event/data/{event_uid}/title
/event/data/{event_uid}/description
/event/data/{event_uid}/startTimestamp/event/data/{event_uid}/endTimestamp
/event/data/{event_uid}/creationTimestamp
/event/data/{event_uid}/isLogicallyDeleted


These indexes allow us to create a two-way relationship between events and the users who we determine will find the event relevant and should be shown it:

/event/index/userToEvent/{user_uid}/{event_uid}/ (value = true)
/event/index/eventToUser/{event_uid}/{user_uid}/ (value = true)


These indexes create a two-way relationship between events and the users that are attending:
/event/index/usersAttendingEvent/{user_uid}/{event_uid}/ (value = true)
/event/index/eventAttendees/{event_uid}/{user_uid}/ (value = true)


At the moment the priority of userToEvent is set to the creationTime so the user can see the events in order they were created.

As per the first post, we're wanting to sort by the startDate, and potentially some other keys so it seems likely I'll need to make the following amend:

/event/index/userToEvent/{user_uid}/{event_uid}/{startTime}
/event/index/userToEvent/{user_uid}/{event_uid}/{creationTime}
/event/index/userToEvent/{user_uid}/{event_uid}/{name}



I'm not overly concerned at the moment with how things will update in the iOS app at the moment - it's easy enough to resolve so we can leave how the user observes the events for changes.

My main concern is with how the data in Firebase will be updated.

It seems likely that we'll need to do the following:

- Given that titles and start dates are unlikely to change very often we could iterating through each user and updating the startTime/name...we'd use multiple workers to speed things up...thousands of users would take a large amount of time.
- In order to make sure each users index is actually updated (in case of a server crash) we need to keep a qyeye of pending updates
- We could make this very generic so that it could be applied to similar case.

e.g.

/updateQueue/events/{event_uid}/{user_uid}/startDate/ (value = true)

- The example tree structure would allow us to quickly replace an existing change of date with a new change of date.
- If a user opens the event before their index was updated, and we detect a change in the startDate/name we can update the index within the app and remove the item in the updateQueue. 


The above will work pretty well but my concern is that this doesn't scale very well and any scaling will start costing a lot of money (all the additional workers). 

So my question comes down to - is this the most optimal way to do something like this?

Thanks again!

Luke
Reply all
Reply to author
Forward
0 new messages