We store device status in Firestore from an Android tablet. This could be if a printer is online or offline.
When the tablet goes offline for a while and comes back, we see a lot of write churn where each write for i.e a printer will be 'played back'. We are really only interested in seeing the last write for a given doc id. Is there a way to tell firebase that newer writes should completely replace older ones before hitting the server, once online?
Is there a way to tell Firebase that newer writes should completely replace older ones before hitting the server, once online?
Yes, there is. You should consider writing the data in the exact same location. When it comes to Cloud Firestore, you should always write the data in the same document. It doesn't really matter how many updates you do while offline, when the device regains connectivity, you'll only get the last update.
Related
I'm using Firebase's Cloud Firestore in an Android application for receiving product information. The Android client only reads from Firestore and never writes. Offline persistency is enabled. The product information is updated once a week.
I've received several reports of customers that claim that they still see outdated data even after I've changed the data in the cloud. These reports come in even days after the import so I guess their smartphone had an Internet connection in the meantime and it's not a connectivity issue.
The point is I could never reproduce this. I've checked the code a few times but don't see any error on my side. I'm reading from Firestore once when the view is rendered. I do not use snapshot listeners.
I know this is all very vague so I'm just asking if anyone else made the same experience with Firestore on Android with offline persistency enabled?
Version of the Firestore library is 17.1.5.
I haven't had the same problem, however, just to help (maybe it's useful), few things to mention here, about how Cloud Firestore works:
First time the client-side SDK fetches, it fetches from the server, saves the results to the cache.
The second time you fetch, the first results will always come from the cache, until you fetch them from the server.
Until you fetch the new values from the server, they will keep coming from the cache.
You have specifications such as Source.SERVER or Source.Cache. If you can't really reproduce this, I might really think that this is something to do with the connection of your customers. However, for you to actually debug this and see the percentage of this happening, I would suggest you to (to actually see the impact and be more data-driven):
Add a timestamp object to your Firestore, whenever you update your information (as per week you say)
Add the same timestamp to Firebase Remote Config for a key
Fetch these in your clients and compare, if not the same, and if the one from Remote Config is never, that means you hit the user group that has the described problem.
Just a dummy test for you to actually see the impact. From my current PoV, I can't help you more than this. However, I would also urge you to bump up your versioning on Cloud Firestore, currently, it's 21.3.0.
I am developing an app which can be used for sharing location between 2 or more devices. One can be a publisher and other can be a subscriber. I got the first part done where I have an app which can read current lat-long from the device.
The second part is to publish it a repository (which is accessible on the internet to other devices also) so that other devices which subscribed to feeds of this device, will get such values and then render location on their devices. i.e. Bus Sending it location and people can subscribe to it to check when it will come near their home so that they leave office to reach bus stop just before 5 mins left for the bus to arrive at their stops.
I am looking where can be the best place to put such date where many devices can read and write (kind of online cache) for my application.
Maybe something like Firebase Realtime Database. Google Cloud Storage is not a good backend for something like this since it doesn't provide synchronization, and it would be hard to separate and authorize access to this privacy sensitive data.
I'll like to know if it is possible to increase the size of the local cache of the firebase firestore database?
Will also like to deepen my knowledge on how firebase firestore offline
data persistence functions on mobile( android specifically).
Let me explain my use case and you evaluate if firebase firestore is the route to go for me.
I require a local database that can be synced averagely after every 24 hours and I require it to function offline and persists it's data. The main use case is this: I have a messaging feature integrated into the application and just as everyone expects to see his messages he's got to send and receive before he was disconnected that is, just as even when one is disconnected, he still can see his different conversations on whatsapp even after a phone reboot, that's how i expect my application to follow and I want to know if firebase firestore local cache offers me this possibility of persisting the cache even after phone reboot without having to connect to the internet? I do expect a lot of reads from the local cache but not that of writes while offline.
To summarize my question, can the local cache persists changes that have been made while the phone was offline even after phone reboots without any connection to the internet? Thank you all for your answers and time taken to read this in advance.
Please, do include some helpful links to tutorials showing how to use it if you do know any of them.
The size of the local cache depends on the size of the storage of your device. If you want to increase the size of your local storage, then you just need to free some space or buy a new hardware. There is no limitation regarding the maximum size that can be stored on your device.
Cloud Firestore supports offline data persistence. This feature caches a copy of the Cloud Firestore data that your app is actively using, so your app can access the data when the device is offline. You can write, read, listen to, and query the cached data. So, Cloud Firestore persists the data you write on a device to a local database. So the next time you start the application, it will indeed be able to read that same data, even when the device has never been connected to the Firebase servers. And as an answer to your question, yes it can.
But don't use Cloud Firestore as an offline-only database. It is really designed as an online database that came work for short to intermediate periods of being disconnected. While offline it will keep a queue of all your write operations. As this queue grows, local operations and app startup will slow down.
Nothing major, but over time these may add up. But remember, all these operation will persist even if you restart the device. You not gonna lose any data.
The Goal: I'm working on a simple project with Android Studio and Google App Engine. The App is just a Proof of Concept, so nothing spectacular. In a sentence, it is an app that counts the number of times a button was clicked in a six hour interval. Specifically, when a button is hit, the app needs to send a request to the backend. The backend then needs to load a number from cloud storage, increment it, and write it back. Every six hours, I need to reset the counter to zero.
The Current Progress: I have the app UI written, I have an App Engine Project set up, and I have the two connected via endpoints. For now, I have a method to send two numbers to be added in the backend and return it. I'll scrap that and go with the incrementor code when the time comes, but I can say I understand how App Engine and Android are connected.
The Problem: How do I access Google Cloud Storage programatically from here? Do I write backend code? Do I write code in the App itself? Do I do some more endpoints wizardry?
I keep seeing code excerpts, however, I don't know how everything fits together. I can access cloud storage from the online manager, however, that doesn't do much good I don't think. I understand how buckets and entities are broken down as well, if that helps.
Thanks in advance, I've been wandering through the desert of Documentation for weeks.
It's a little unclear exactly what you're trying to accomplish, but I'll take a crack at hopefully nudging you a bit more in the right direction.
First off, if you're just needing to load and increment a number, in my opinion, you may be far better served using a database, such as Google's Cloud Datastore, rather than Cloud Storage.
There are numerous options for connecting, whether you end up on Cloud Datastore or Cloud Storage. You may find it easiest to implement your Storage/Datastore operations on App Engine, but that really depends on what else you're doing.
If you app just needs to do basic database or storage operations, I wonder if you might not be far better served by a more managed solution like Firebase. With Firebase, you get many of Google's cloud services, nicely wrapped in an API that is very easy to implement, thereby negating the need to manage a separate App Engine instance and your endpoints. Firebase also gives you offline and caching functionality.
as you know, we can access to any folder on android device after rooting. My app has a database and some other binary files. I know that I can't prevent user see my files and database. But is there any way to prevent user copy it to other android devices for illegal use?
One option is to encrypt the data stored in database. Normally it is stored in plaintext. SQLCipher, I believe works for Android too..
From Android/google official forums,
Users with rooted phones can get access to any files they want.
Otherwise, databases in the conventional on-board flash location are
secure.
If you want to prevent that (routed access) only option is to encrypt it. However long it takes.
EDIT:
What I am saying is, it is never completely secure. You can make it as much difficult for hackers. You can save the decryption key (only) in the server (if downloading entire data from server is time consuming) but then app needs net connection to work. You can save the key in a hidden file (filename starting with .), but rooted users with knowledge about linux type file system can find them. Or you can do as Teovald suggests it in the comment to this answer, by generating the key in run time using any hash algorithm from any constants (like IMEI number), but it also need some processing. The more you try to secure it, the more works you need to do to use it. So it is a 50-50 kind of situation, and decision should depends on one's requirement.
Apart from encryption (see Krishnabhadra's answer) the only way to ensure critical data is to not have everything on the device. So you could access the most critical data always online only.
Of course this has the downside that not all of your app is usable if the user has no connection. You have to balance between your need to keep data safe from prying and allowing instant offline access to data.
If you can alleviate the former problem depends on the data. If all is critical, nothing is allowed on the device. Users will understand and begrudgingly accept this. No one would want a copy of his bank account on his device. But you should allow access to everything that is not critical even in offline mode.