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
Currently I have written custom LiveData class, which adds snapshot listener to document reference while being observed, thus providing easy way to update UI. I want to continue listening to the same document after app closes, and show updates in notification.
What would be a good way to do that? I have little experience with services, etc. but if I understand corectly, I should use either WorkManager or foreground service. Is there a solution which would allow to use the same listener for UI and background?
Most answers to similar problems suggest using FCM + Cloud Functions to send updates, but for my purposes I would like to have ongoing notification and also I've experienced delays with cloud functions, so I'd like to avoid going this way.
The way you'd like it to work is simply not possible anymore these days.
When your app is backgrounded on Android, the operating system will reduce its resources usage over time. This means that you can't rely on Firestore's usual mechanism to receive updates from the server, not even in a background service.
The idiomatic way to deliver updates to an app that is not active in the foreground is (as you've found) to send FCM messages to that app from a server or Cloud Functions. If you're having trouble making this work, we'll be better able to help if you post the minimal, complete/standalone code with which we can reproduce where you got stuck.
So, I wanted to use a Firebase Listener in the background because there's some code I need to trigger while the app is closed based on Database values. I thought I could just throw the listener on a Service, however reading the docs looks like Services are no longer a good option because of how the OS works in recent versions.
I found about the WorkManager class which supposedly is the best new option to implement background code and it looks fine and all however the 15 minutes minimum time for periodic jobs is way to much time for what I need.
So I was wondering what could be the best practice possible to use a Firebase Listener on the background? Or should I just abandon the idea of using a listener on the background at all?
You can't force a listener to stay live while the app has been backgrounded. This is because Android can (and will) kill the app process when the user isn't using it any more. Your connection to the database will be lost.
You could use WorkManager to wake your app periodically to check the database, but that doesn't sound like what you want.
The preferred solution is to use Firebase Cloud Messaging from a backend you control to ping the app when you know there is new data it's interested in.
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.
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.