Is Firedatabase.SetPersistent (true) minimiza downloading data? - firebase

Using
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
Is this guarantee to download the data only one time across the App life/App restarts even if the user has good connection?
N.B: The official docs isn't clear ( at least for me) at this point.
By enabling persistence, any data that the Firebase Realtime Database client would sync while online persists to disk and is available offline, even when the user or operating system restarts the app. This means your app works as it would online by using the local data stored in the cache. Listener callbacks will continue to fire for local updates.

The sole goal of enabling persistence is to ensure that the app continues to work, even when the user starts it when they don't have a connection to the Firebase servers.
The client does send tree of hash values of its restored local state to the server when it connects, which the server then uses to only send the modified segments back. But there is no guarantee on how much data this sends or saves.
If you want to learn more about what Firebase actually does under the hood, I highly recommend enabling debug logging and studying its output on logcat.
For more on the topic, see these questions on Firebase's synchronization strategy.

Related

How to use firebase realtime-database in offline mode in Flutter app?

I came across a wonderful feature of Firebase offline feature. I integrated that in my app just by writing one line of code in my main.dart file after initializing Firebase await FirebaseDatabase.instance.setPersistenceEnabled(true);
Question 1 :
I couldn't able to understand the database.keepSynced(true) function because without using this line of code, my app is persisting old as well as fetching new updated data, so what this exactly does ?
Question 2 :
How could I prevent the write operations when a user is offline, because I read that after setting persistence enabled, it makes a queues of write operations and update them when user gets online, so how could I stop this ?
Question 3 :
Is this persistence feature going to work in IOS device as well or need some permission settings first ?
Thanks
When you call FirebaseDatabase.instance.setPersistenceEnabled(true) you're allowing Firebase to create a local file on the device where it persists any data it's recently read, and all writes that are pending while the device is offline.
When you call keepSynced(true) on a node, you are telling the SDK to always keep that node synchronized. It essentially creates a onValue listener on the node without any handler code, so you're purely doing this to keep the data synchronized for when the device does go offline.
By combining keepSynced(true) with setPersistenceEnabled(true), you're specifying that you want the app to continue working when it's offline across restarts, and which data is needed for that.
If you call keepSynced(true) on the root of your database, you're telling the SDK to synchronize all data in the database to the disk cache. While this may initially be a quick way to get offline mode for your app working, it typically won't scale when you more people start using your app.
If you only want to allow write operations while the client has a connection to the database backend, you can register a local listener to the .info/connected node, which is a true value when there is a connection and false otherwise.
Note that Firebase doesn't require this, as it queues the pending writes and executes them when the connection is restored. In general, I'd recommend working with the system here instead of against it, and also trying to make your app work gracefully in the offline scenario. In many cases there is no need to disable functionality while the app is offline.
Offline disk persistence is available on Android and iOS, but not on web.

Firebase Firestore not showing documents created by my flutter application

I was able to configure the Firestore database in Firebase with my flutter app and also create and read documents from my collection but when I go to Firestore console I don't see the created data, also when I creat data manually I am unable to see it in my application.
I am using the test mode which means any user can read or write.
I hope someone can help me with this puzzle.
Thanks!!!
It sounds like the device/emulator that you are running on is not connected to the internet, or at least not to the Firestore servers. In that case, the client writes all local changes into a local database, waiting to send them to the server when it gets a connection. So the local app will work, but won't be able to synchronize its local cache with the database servers.
You might want to check the connection on your device, and any proxies that might exist between your app and the Firestore servers.

Is transaction really required in a distributed counter?

According to firestore documentation:
a transaction is a set of read and write operations on one or more documents.
Also:
Transactions will fail when the client is offline.
Now the limitation in firestore is that:
In Cloud Firestore, you can only update a single document about once per second, which might be too low for some high-traffic applications.
So using cloud functions and running transactions to increment/decrement counters when the traffic is high will fail.
So they have discussed to use the approach of distributed counters.
According to the algorithm of distrbuted counter:
create shards
choose a shard randomly
run a transaction to increment/decrement the counter
get all the shards and aggregate the
result to show the value of a counter
Scenerio:
consider you have a counter which is to be updated when a document is added and that counter is being displayed in the UI. Now for good UX, I cannot block the UI when network is offline. So I must allow creation/updation of documents even when client is offline and sync these changes once client is online so that everyone else listening to these changes receive the correct value of the counter.
Now transactions fail when the client is offline.
So my question for best user experience (even when offline) is:
Do you really require a transaction to increment a counter? I know
transactions ensure that writes are atomic and are either
successful/unsuccessful and prevent partial writes. But what's the
point when they fail offline? I was thinking maybe write them to local cache and sync it once the network is back online.
Should this be done via client sdks of via cloud functions?
Do you really require a transaction to increment a counter?
Definitely yes! Because we are creating apps that can be used in a multi user environment, transactions are mandatory, so we can provide consistent data.
But what's the point when they fail offline?
When there is a loss of network connectivity (there is no network connection on user device), transactions are not supported for offline use. This is because a transaction absolutely requires round trip communications with server in order to ensure that the code inside the transaction completes successfully. So, transactions can only execute when you are online.
Should this be done via client sdks of via cloud functions?
Please note, that the Firestore SDK for Android has a local cache that's enabled by default. According to the official documentation regarding Firestore offline persistence:
For Android and iOS, offline persistence is enabled by default. To disable persistence, set the PersistenceEnabled option to false.
So all read operations will come from cache if there are no updates on the server. So Firestore provides this feature for handle offline data.
You can also write a function in Cloud Function that will increment the counter while a new document is added or to decrement the conter while a document is deleted.
I also recommend you to take a look:
How to count the number of documents under a collection in Firestore?
So you may also consider using Firebase realtime database for that. Cloud Firestore and Firebase realtime database work very well together.
Edit:
It allows one to upvote the answer even when the device is offline. After the network is online, it syncs to the server and the counter is updated. Is there a way i can do this in firestore when the device is offline.
This is also happening by default. So if the user tries to add/delete documents while offline, every operation is added to a queue. Once the user regains the connection, every change that is made while offline, will be updated on Firebase servers. With other words, all queries will be commited on the server.
Cloud fnctions are triggered only when the change is received and that can only happen when the device is online.
Yes, that correct. Once the device regains the network connection, the document is added/deleted from the database, moment in which the function fires and increases/decreases the counter.
Edit2:
Suppose I have made around 100 operations offline, will that not put a load on the cloud functions when the device comes online? What's your thought on this?
When offline, pending writes that have not yet been synced to the server are held in a queue. If you do too many write operations without going online to sync them, that queue will grow fast and it will not slow down only the write operations it will also slow down your read operations. So I suggest use this database for its online capabilities.
Regarding Cloud Functions for those 100 offline operations, there will be no issues. Firebase servers work very well with concurent operations.

How do I communicate / trigger a Webtask from Firebas?

In an interesting blogpost about 'Firebase Authentication with the Firebase 3.0 SDK and Auth0 Integration', it is stated that:
You can even have Firebase communicate with Webtask!
Now I can imagine the (web)client triggering a Firebase operation and subsequently a Webtask, but not the other way around. Or am I missing something?
Firebase can run as a serverless app, but it can also run on the server. You can even have Firebase communicate with Webtask! (sic!)
I think that paragraph is misleadingly phrased, perhaps it was just added at the last minute to spark interest. You can have a webtask communicate with Firebase, not the other way around. You don't "run Firebase" on your server either.
TL;DR: A client application may call a webtask with an HTTP request, and that task can read/write the database, but not in any other order.
Here's a quick and dirty reality check as of Nov. 2016:
The Realtime Database by itself does not provide you with a way of executing code. This includes responding to database changes and user requests, handling fan-in and fan-out operations, etc. There is no support for webhooks either.
Which means you have to provide your own execution environment for such logic on a custom server, or you can try to cram as much as possible into the client code. This is a pretty exhaustive topic by itself.
Webtasks are short-lived functions that respond to HTTP requests. Their lifecycle always starts with a request, so they are not fit for continuously watching the database for changes. But they are perfectly valid for handling requests coming in from your client application.
As you can store "secrets" for the webtasks, you can authenticate the task on an admin access level. This gives you the possibility to verify client tokens – which should be sent along with the request –; perform complex authorization and validation, and perform RTDB write operations you wouldn't trust the clients with.
Or trigger external services securely. The possibilities are close to endless.

Current status of Meteor for offline application

There are some threads on SO that cover this - but most of them are 12 months old. I want to understand if Meteor (and available packages) is currently capable of handling:
An App that runs both online (when there is network connectivity) and offline (when there is not).
Allows changes made while offline to be persisted to the server when online (and the reverse).
Allows the data that is persisted to be stored encrypted on the device and only decrypted when used.
Allows some attribute of the user (application password, or possibly a token generated by the server for each logon) to be used as part of the decryption key. (intent is that if the device is stolen and the screen lock bypassed the data is still "reasonably" safe).
On both IOS and Android, rooted and not.
Quoting my own reply on Reddit:
when you export let's say an apk from Meteor, this is a self contained app? this app connects o a server? does it work offline by default?
Yes, theoretically they will work offline. They do work offline now, but they cannot get new data from the server or execute remote procedures on the server w/o a connection (makes sense, right?).
If you want a fully offline app, you can try to use one of the community packages for the offline data support: https://atmospherejs.com/ground/db

Resources