The firestore documentation says:
Cloud Firestore caches data that your app is actively using, so the app can write, read, listen to, and query data even if the device is offline. When the device comes back online, Cloud Firestore synchronizes any local changes back to Cloud Firestore.
Now, I have tested this and, apparently, device coming back online is not all that it takes for the synchronization to happen.
I tested that by:
Turning on "Airplane mode" on my emulator
Trying to send a data to firestore*
Closing my app
Turning off "Airplane mode" on my emulator
* I used FirebaseFirestore.getInstance().collection("foo").document().set(bar)
On the end of this test, the data was not sent to firestore remote database. I needed to open my app again in order for the data to be sent.
But then, I still wasn't sure what exactly was triggering the synchronization. Is it only my app being open or does it needs to have an open socket to firestore?
I tested one last thing, which was:
Turning on "Airplane mode" on my emulator
Trying to send a data to firestore*
Closing my app
Altering my code so the app stays on the splash screen
Turning off "Airplane mode" on my emulator
Opened my app
On the end of this test, the data was not sent to firestore remote database.
But then, once again, I still wasn't sure what exactly was triggering the synchronization. It's probably the open socket, but if so, does it need to be open on a query related to my collection?
My final question is:
What exactly does trigger the synchronization?
Is it only my app being open or does it needs to have an open socket to firestore?
It depends on what "my app being open" means. If it means on foreground, that might not make too much sense since you can have jobs running on background with an open socket to Firestore.
It's probably the open socket, but if so, does it need to be open on a query related to my collection?
No, it does not. Any CRUD action on any part of your database will make the synchronization starts, whether it is by querying through a collection or fetching, saving, updating or removing a document.
Related
I'm writing a chat application with the help of firebase.Here I have a problem , if the device is offline the data is stored in cache and when device is back online the cache will be synced , but how to know which data is synced and which not (User may have poor internet connection , so syncing may be delayed).How to notify user that message has been sent or sending , and that too we need to manage a huge list of messages
Thank you!
There are two ways:
Using a completion listener as shown here: Firebase Android - how to tell if node has been synced This approach works as long as the app stays active. Completion listener don't survive an app restart, so it won't work if the app is restarted.
Using a sentinel value. Writes to the database from a single client are guaranteed to be executed in order. Using this knowledge, you could write a sentinel (think: dummy) value when the app is restarted, or the connection is restored, and detect when that one is written. Once the sentinel value is confirmed, you can be certain that all older messages have also been handled by the server.
Also see:
Firebase synchronisation of locally-modified data: handling errors & global status
My app loses connection to Firebase Realtime Database after being put in the background for a while ... In other words when I reopen my app again after being in the background for a while, Realtime Database services stop functioning until I clear the app data at the phone settings and everything back to normal ... I read about similar cases and found out that Android destroys resources (Socket connection) with Firebase after being put in the background for a specific period of time. However, there was no straightforward solution provided to restore connection after going back to the app ... so any help ?
It is expected that apps will lose their socket connections when there is no visible activity. That's the way the Firebase SDK works. Also, Android will aggressively pause background applications so they don't consume data and battery when the user isn't actively using it.
When an activity becomes started again, the Firebase SDK should attempt to restore the websocket it uses to communicate with the server. This websocket is fully managed by the SDK. You don't have to do anything to tell it to reconnect.
I'm considering the use of keepSynced() for some data from Firebase Realtime Database. I understand that it will automatically sync those paths. But how does that relate to Android lifecycle? If the user leaves all activities (and all normal listeners disconnect), will it stop syncing? I don't want the app to become data or battery hog.
On the other hand, I would like to update cached data when FCM notification arrives. I can launch some service which will connect to Firebase. I would like to sync all paths which are in keepSynced() and stop it when it's synced. I'm not sure how to achieve that. Create a listener to one of the paths and keep the service running for some time? After the service is finished, will it stop syncing?
firebaser here
Great question!
When there is no active activity, the operating system may close the connection to the Firebase database at any time. Our SDKs don't try to prevent that, but will reconnect when the app becomes active again.
What you're describing in your second paragraph is what we call "push to sync", where you send a push notification (typically a silent FCM data message) to trigger synchronizing of the data.
We did something like that in last year's I/O app and, while it was a bit more complex than we wanted it to be, it worked great. We explicitly managed the connection in that case, calling goOnline() and goOffline() (after 5 minutes iirc). The main sync code can be found in the IOSched github repo.
Is there anyway that I can read the data from the real time database of firebase and can save it while the app is not opened, I am using Firebase.getInstance.goOnline();
in the code whenever Network connectivity changes so that it listens the data.
I am able to write the data in the database if app is not in recents or is not opened but in the same way I am unable to read the data when app is not opened. Is there any possible way ? Or I am going for an wrong approach ?
I just wants that whenever network connection will be available it will download the updated data automatically. , so that later on I can see the updated data being offline.
Any help will be highly appreciated. Please.
Android makes no guarantees about whether or not your app process is running when it's not visible on screen. It could be killed in favor of other processes that are a higher priority for the user. So, in general it's not a good idea to assume that you can do networking any time you want.
Also, newer Android devices will go into doze mode to help save the user's battery. In that case, your app will definitely not be running.
If you want to ensure that your app process is running, you can schedule some time with JobScheduler or AlarmManager. Or you can ping your app from your server with Firebase Cloud Messaging.
I'm considering the use of keepSynced() for some data from Firebase Realtime Database. I understand that it will automatically sync those paths. But how does that relate to Android lifecycle? If the user leaves all activities (and all normal listeners disconnect), will it stop syncing? I don't want the app to become data or battery hog.
On the other hand, I would like to update cached data when FCM notification arrives. I can launch some service which will connect to Firebase. I would like to sync all paths which are in keepSynced() and stop it when it's synced. I'm not sure how to achieve that. Create a listener to one of the paths and keep the service running for some time? After the service is finished, will it stop syncing?
firebaser here
Great question!
When there is no active activity, the operating system may close the connection to the Firebase database at any time. Our SDKs don't try to prevent that, but will reconnect when the app becomes active again.
What you're describing in your second paragraph is what we call "push to sync", where you send a push notification (typically a silent FCM data message) to trigger synchronizing of the data.
We did something like that in last year's I/O app and, while it was a bit more complex than we wanted it to be, it worked great. We explicitly managed the connection in that case, calling goOnline() and goOffline() (after 5 minutes iirc). The main sync code can be found in the IOSched github repo.