7

I've been reading a lot on S.O. about offline (local) storage and AngularFire, and I understand that AngularFire is intended for 3 way binding usage with the Angular model and DOM.

With specific reference to How to sync offline database with Firebase when device is online? I can see that it's not a trivial matter introducing local storage into the mix. I didn't quite understand the concept of "priming" Firebase in that thread.

However, I do need to be able to start the app in offline mode. Here's my scenario:

  1. I'm building a guest list app, which can run simultaneously on multiple devices, using Firebase as the backend store for the guest list.
  2. If a device checks a guest in, it propagates to FB and hence to the other devices. It should keep an up to date copy of the guest list in local storage.
  3. Where I live, 3G coverage is a significant problem, so somebody may load the app when they're connected, close it, move to another location and then try open the app when there's no signal.
  4. In this scenario, the app should use the local storage guest list.
  5. When the device comes online again, connect to Firebase and upload local storage changes to Firebase.

I know Kato also has mentioned that there may be offline storage capabilities coming in a future release of AngularFire - is that still a possibility? Otherwise my thinking is to do this:

  1. Assuming the app has started in offline mode, every time a guest is checked in, update local storage. Also keep track of that change in a local storage "changes made" var.
  2. When / if the device comes back online, use AngularFire to pull the Firebase guestlist into a $scope.guestList variable.
  3. Loop through the list of "changes made" from local storage and make those changes to the $scope.guestList var.

It doesn't feel like a good approach, but I don't know of any other way. Is there a way to directly bind Firebase to local storage?

Community
  • 1
  • 1
quijames
  • 537
  • 1
  • 5
  • 19

1 Answers1

5

I've decided that it is probably better to not be using AngularFire in this scenario, but rather to use the Firebase SDK directly. The 3 way binding of AngularFire makes it very difficult to intercept $scope changes to put into local storage. Using SDK directly allows you to intercept FB changes and save those directly to local storage as well as updating the $scope.

Similarly, making changes to FB using ref.update() is trivial and can be done alongside to updating local storage.

If the app starts in offline mode (detected from .firebasio.com/.info/connected) then simply use local storage, but also as Kato suggested "prime" the Firebase connection. I'm doing this by simply calling a blank ref.update({}); . Then when making changes to the data in local storage, also run your normal FB updates / push / save. Then when the app connects, the in-memory FB copy will sync with the server.

quijames
  • 537
  • 1
  • 5
  • 19
  • The issue I have with this is your set or updated data will overwrite the firebase copy once connected. Set for example will wipe out your children items so you have to call update. Lets say your system disconnects at 9PM but at 10PM something on firebase was updated by another client. Then at 9AM your local copy(which is disconnected still) adds an update to the local version of firebase, the timestamp will show your local copy as newer and overwrite the server data.. We combat this by only giving read access but it isnt a perfect solution – Dennis Smolek Apr 05 '15 at 23:21
  • @DennisSmolek you have to implement server side or client side logic for that – Hollerweger Sep 24 '16 at 10:45
  • @Hollerweger not sure what you mean.. If two clients were to write that "Event A" has changed and client1 was connected while client2 wasn't as soon as client2 connects it will overwrite the changes client1 made. We ended up writing an update collection that stores with a datestamp. Only connected clients can pull and save their records to the live DB. – Dennis Smolek Sep 24 '16 at 15:56