What Triggers the Firebase DISCONNECTED and NETWORK_ERROR DatabaseErrors? - android

I'm writing an Android application that uses the Firebase RealTime Database and Firebase Cloud functions. Several of my cloud functions are triggered by writes to the RealTime database and are used further process data saved by the Android client application.
I'd like my app to handle network connectivity changes gracefully. I understand that Firebase handles loss of connection by saving changes to the RealTime database locally and then syncing the changes to the server when connectivity is restored. This is well documented in the Firebase Documentation.
In my case though, since I need the Cloud Function post-processing of data saved to some paths to have occurred before it is useful, there's no point in having this data saved if it isn't going to make it to the server (and therefore trigger a Cloud Function), in a timely manner.
I'm using the updateChildren function from DatabaseReference to save the data and have a CompletionListener attached to monitor the outcome. I thought I may be able to use the DISCONNECTED and/or NETWORK_ERROR DatabaseErrors to identify cases where my data won't be reaching the server. However, if I interrupt the network connection before updateChildren is called, there aren't any errors generated. In this case, Firebase has likely saved the data locally with plans to sync it later, so updateChildren is considered to have been completed successfully.
My questions then are:
When are the DatabaseErrors DISCONNECTED and NETWORK_ERROR actually used by Firebase? Can I use them in some way to help manage connectivity issues?
What are the best practices for handling cases where Firebase data must make it to the server in order to be useful? Should I really just be POSTing my data to the Cloud Function directly?
Does Firebase have any notion of a timeout period that can be watched and data invalidated if it isn't synced within a specific period of time?
Yes, I recognize that I can use a listener attached to /.info/connected to detect changes in the connection state, but I'd rather be able to react and gracefully handle my case as it happens. I feel that my usage of the Realtime database together with Cloud Functions is common enough that there must be generally accepted way to implement it.
Any thoughts appreciated. Many thanks.

Did you try OnDisconnect method of firebase realtime database ?

Related

Firebase Realtime Database do broadcast operation even when there is no subscriber

Recently I have came across with problem that Firebase Realtime Database generates too much download traffic.
In my application I only write to the database using:
database.child("child").setValue(value)
While researching the problem with Firebase's database profiler I found that there is listener_broadcast operation on each write operation and that broadcast generate download traffic despite the fact that I do not subscribe to read data anywhere.
Does anybody know how to fix this problem. Namely I would like to disable this broadcast operation

sync local db (Sqlite) with server db android

I want to create a POS application but for some reason the application should be working when there is no internet connection (and later do the synchronisation when connect to internet). the only method that came to my mind is synchronising between local db with server but I dont have idea how to or the best method to do this. I have several question about this:
is it possible to use FCM cloud messaging to do this ? I mean Client A tell FCM data has changed, and then FCM tell several clients (phone) to do sync db in the background without user's (phone owner) confirmation (automatically).
or the only way is to use this method https://github.com/codepath/android_guides/wiki/Server-Synchronization-(SyncAdapter) ? if it's so, how often we can synch db local with server? is synchronising each 3 minutes will be fine?
Yes, use FCM real-time database for this. FCM manages data for you internally on the app, as well as on the cloud. So if you write some data into your JSON tree but you don't have internet connection, the data will be pushed into the cloud once the connection is available.
The documents clearly state this (Read last section on 'Writing Offline Data': https://firebase.google.com/docs/database/android/read-and-write
Also, any data added to the database when your client was offline will be sent once the client goes online - because the real-time database keeps storage of the data as well.
Using a server-sync every 3 minutes is not feasible - and it is more likely that your app will get killed by the system at some point or the other. Use FCM and Cloud Functions along with JobSchedulers to get the best result.

Firebase Realtime Database: optimizing for local usage

In my use case, the data is only written by client, not by server.
But I would like to use Cloud Functions on the server, whenever a change is made on the client.
What I would like to avoid is to re-download the data from the server if it's already locally stored.
I found out is it possible to enable disk persistance:
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
Can anyone explain if this actually prevents re-downloading data in case it's already locally stored, or the data would periodically re-downloaded anyway?
Generally speaking, which is the criteria by which the data is re-downloaded? Is there a sort of hashcode check between client and server data to find out if the data has changed?
Calling setPersistenceEnabled(true) enabled Firebase's disk cache. It's primary purpose is to ensure your app continues to work when there is no network connection. In addition it may reduce data transfer, but that depends on quite a few variables.
For some more information on what disk persistence means, how it interacts with Firebase's in-memory caching of data, and more, see:
Firebase : What is the difference between setPersistenceEnabled and keepSynced?
Firebase offline capabilities as cache
Firebase Offline Capabilities and addListenerForSingleValueEvent (just an interesting/annoying edge-case)

Firebase how to detect if cached data is available

I have an application that pulls some simple data from Firebase Realtime Database, and to make things simple here is the flow that I want to have.
If phone is connected to the internet:
Get the data from the firebase database
If phone is offline
If there is data in firebase cache -> get data from cache
If there is nothing in firebase cache -> show some default data stored locally in app
The problem is that I don't see possible way to detect if data is available in firebase cache. So when phone is offline I cannot see if I should display the locally stored data or cache from firebase database.
Agree above answer, Firebase will do it for you, if you do it in the right way. In order to solve your problem, you should understand the difference between the two approaches of firebase offline cache - reading-from-memory and reading-from-disk.
Read this article -> https://pamartinezandres.com/lessons-learnt-the-hard-way-using-firebase-realtime-database-c609b52b9afb
in your case, just add, FirebaseDatabase.getInstance().setPersistenceEnabled(true); to enable reading from disk
and add yourReferenceForFirebase.keepSynced(true); to keep the data synched
then your app will work as you expected.
But, only this part: "If there is nothing in firebase cache -> show some default data stored locally in app", seems impossible.
Firebase does it for you.
Firebase applications work even if your app temporarily loses its network connection.
Also firebase apps automatically handle temporary network interruptions.
Cached data is available while offline and Firebase resends any writes when network connectivity is restored.
If it is not enough and you need to work offline you can also enable the disk persistence just adding:
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
More info here.
EDIT:
There is no way to know whether a value comes from the local cache or from the remote server.
There is only a way to know if your app is currently connected to the Firebase Database server.
To achieve it you can detect the connection state by listening for the .info/connected value.

Firebase' true offline capabilities

I'm trying to find out how far the offline capabilities of Firebase on Android actually go.
As far as I understand, it should be possible to make the Database "persistent" with FirebaseDatabase.getInstance().setPersistenceEnabled(true);
The documentation reads:
The Firebase Realtime Database stores data returned from a query for use when offline. For queries constructed while offline, the Firebase Realtime Database continues to work for previously loaded data. If the requested data hasn't loaded, the Firebase Realtime Database loads data from the local cache. When we come back online our data will load and reflect the query.
Is this also true when the offline state is beeing forced by goOffline?
In this question the user got an answer from firebase support:
While you can use goOffline() to force the client offline for a long time, performance will deteriorate over time. The Firebase clients will queue intermediate state changes, instead of updating the stored state as the server does.
Does this mean the "local database" isn't actually updated like it would be when offline due to connection loss?
Because most of the time any query or value event listener doesn't come back, onDataChange is never called as is onCanceled (I checked!)
If only the connection is lost, it actually works as advertised, although sometimes with up to a minute delay, which seems to be a problem on its own.
What is then the intention of even offering the goOffline() method if this just stops the interaction with the database completely?
In my implementation the app starts offline, with an anonymous authentication. So in the beginning of course the "local database" will be completely empty. But shouldn't the value events at least fire onDataChanged with an empty datasnapshot?
I tried staying online until I received the anonymous UID and added an empty entry into firebase database, which then is queried/cached. After that if I call goOffline, no more entries can be added and no more queries will be answered.
Similar to the above mentioned question, my plan is to offer the user the option to stay offline, with of course the downside of the build up of stored write events in the local cache (but that shouldn't be that big of a problem as there isn't that much data)
So how can I make this work if even possible at all?
The only thing I can see is to have some different database solution in the beginning for actual offline capabilities which has to be translated & transferred to firebase when the user chooses to go online.

Categories

Resources