Thanks to both of you for the replies and info; it's been helpful. Let me give an outline of how I'm structuring my database and perhaps you can advise further. I've tried to follow the best practices docs and have set up the database to be pretty flat; i.e., if x is a model object that has numerous y model objects that it owns, then I've represented that in the database as follows:
{ "<x's_path_name>":
"<x1_UUID>": {
"<x1_name>": ".....",
"<y's_path_name>: {
"<y1_UUID>" : true,
"<y2>UUID>": true,
....
}
...
},
"<y's_path_name>":
"<y1_UUID>": {
"<y1_name": "...."
}
}
}
After the user authenticates, the app would show all the x objects in a tableview and clicking on any x object would then show another tableview with all its associated y objects. Given that there doesn't seem to be a way to do a batch query of a node for a list of UUIDs contained in it (i.e., "return all y children at <y's_path_name> with matching UUIDs from <x's_path_name>/<x1_UUID>/<y's_path_name>"), I attach listeners individually to each y UUID found in <x1_UUID>/<y's_path_name> when I want to return all y objects associated with x when the user would tap on a tableview cell that represents x. I believe I read something on a SO discussion from possibly Frank that this was the recommended way to do these types of bulk read operations. In my actual use case, this structure is much more "nested," in that y
would have z objects set up in a similar fashion to how x has y objects
set up, and there's another level down. I thought of attaching a listener that would fire anytime there was a change to <y's_path_name> dictionary, but it will have loads of y objects belonging to various users and I don't think it'd be practical to fire off an observer anytime there's a change—would require tons of local filtering operations.
After going back and looking at the existing app behavior further, I'm seeing that the offline behavior you say should be happening is partially occurring: It's working for calls to `updateChildValues()`. I call this to perform deletions and edits to x and y. When I do this, my `observe()` handler fires for that reference and when connectivity is regained the completion handler for `updateChildValues()` fires—sounds like expected offline behavior from what you said.
However, what's not working when the app is offline is multi-fold:
1) If do a clean install and am on the tableview displaying x objects, the app goes offline, and a tableview cell is selected, nothing is retrieved for all its associated y objects. This makes sense, as I haven't attached listeners to the associated y objects before connectivity is lost—Kato mentions about a complete local copy of the database not being made by default (understandably).
2) However, if I go back online while sitting on that same empty y object view, force-quit the app after those y objects have been loaded successfully (they're loaded as soon as connectivity is regained), come back into the app, go offline after the x objects have loaded, and then tap on the same x cell whose y objects had already been loaded, none of those y object observers fire.
3) No calls to `setValue()` when the app is offline are causing x's reference `observer()` to fire. I use this method to add new objects to the database. So, what I'd do to add a new y3 object to x1 would be to first call `setValue()` on <y's_path_name> with all of y3's data, then call `setValue()` on <x's_path_name>/<x1_UUID>/<y's_path_name> and pass it a dictionary of { "<y3_UUID>": true }.
So, given this lengthy response (sorry in advance for it!), what do you recommend? To fix #1 above, I could load my entire object graph for a given user's x and y objects when the app starts but that doesn't sound ideal. I could also call `keepSynced()` on individual refs, as Kato said—think this could solve #2. Not sure what I can do to solve #3.
Thanks,
Evan