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.
Related
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.
i'm creating android app, and using Firebase.
I have 'Missions', and 'Mission' have status.
If the status changes to 'Active' - I need to 'Wake up' my app and run the code of 'ActiveMissionActivity'.
(The work of the service should be just 'Waking up the app' and go to another activity)
I could write missionsDbRed onChildChanged listener which will be activated when the status is active - but only when the app is running.
What is the good practice for this issue? My friend suggested me to use 'Android Service', but i'm not sure which type do I need, and if there is something that works well with the Firebase DB.
For example i've seen 'Firebase Cloud Functions' But i'm not sure which one is more suitable and why. Thanks
As push-notifications are not a solution to your issue, the best way of handling this matter is by building a service that checks (in the database) if the value you are interested in has changed.
Now regarding the service, a bad idea would be to run a service that continuously checks that value. This would result in a huge battery drain and you risk your process to be killed as android is freeing up resources. you can notice this here.
You can fix this by telling the service when to start checking the value you are interested in.(e.g. by using Alarm API and assuming you know when this should happen) You can see something similar here.
Keeping your service alive as less as possible is probably the safest way.
As for google cloud functions, you might wanna use those for sending notifications prior to the actions that happen through the service you established.
So if the status changes to active while your app is closed, so that means the value changed somewhere out of your app right? If that's the case simply send a push notification to users device to wake it up. It is a lot more performant than using a background service.
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.
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.