How to persist Firebase objects to disk in iOS? - ios

It seems that Firebase iOS implementation doesn't support offline caching of the client model. What this means in practice that:
For Firebase apps requiring an authentication, you need to first authenticate and wait Firebase finish the login (check the user identity, open a socket, etc.) before you can start moving the data. This will require 1-8 seconds (usually 2-5) depending on the network conditions, at least here in Finland.
After authenticating, Firebase first downloads the initial set of data and initializes the client cache. The time to perform this depends on the size of the data you add listeners for, but it's usually quite fast.
The problem here is that if you're using Firebase to implement, for example a messaging app, you'd most likely want to show the user a previously cached version of the message threads and messages, before the actual connection with the backend server is established.
I'd assume the correct implementation for this would need to handle:
The client-side model <-> Firebase JSON mapping (I use Mantle for
this)
Persisting the client-side model to disk (manual implementation using NSKeyedArchiver, or Core Data or such?)
Synchronizing the on-disk model with the Firebase-linked model in memory, when the connection is available (manual implementation?)
Has anyone come up with a solution (own or 3rd party) to achieve 2) and 3)?

It seems Firebase has solved this problem since this question was asked. There are a lot of resources on Offline Capabilities now with Firebase, including disk persistence.
For me, turning on persistence was as simple as the following in my AppDelegate:
Firebase.defaultConfig().persistenceEnabled = true
Assuming your app has been run with an internet connection at least once, this should work well in loading the latest local copy of your data.

There is a beta version of this technology within the client for iOS described here: https://groups.google.com/forum/#!topic/firebase-talk/0evB8s5ELmw give it a go and let the group know how it goes.

Just one line required for persistence with Firebase in iOS
FIRDatabase.database().persistenceEnabled = true
Can be found here in Firebase Docs

Related

How to ensure the integrity of data sent to the database from my application?

I am currently creating an iOS application with Swift. For the database I use Firebase Realtime Database where I store among other things information about the user and requests that the user sends me.
It is very important for my application that the data in the database is not corrupted.
For this I have disabled data persistence so that I don't have to store the requests locally on the device. But I was wondering if it was possible for the user to directly modify the values of the variables during the execution of my application and still send erroneous requests.
For example the user has a number of coins, can he access the memory of the application, modify the number of coins, return to the application and send an erroneous request without having to modify it himself.
If this is the case then is it really more secure to disable data persistence or is this a misconception?
Also, does disabling access to jailbroken devices solve my problems? Because I've heard that a normal user can still modify the request backups before they are sent.
To summarize I would like to understand if what I think is correct? Is it really useful to prevent requests to save locally or then anyway a malicious user will be able to modify the values of variables directly during the execution and this without jailbreak?
I would also like to find a solution so that the data in my database is reliable.
Thank you for your attention :)
PS : I also set the security rules of the db so that only a logged in user can write and read only in his area.
You should treat the server-side data as the only source of truth, and consider all data coming from the client to be suspect.
To protect your server-side data, you should implement Firebase's server-side security rules. With these you can validate data structures and ensure all read/writes are authorized.
Disabling client-side persistence, or write queues as in your previous question, is not all that useful and not necessary once you follow the two rules above.
As an added layer of security you can enable Firebase's new App Check, which works with a so-called attestation provider on your device (DeviceCheck on iOS) to detect tampering, and allows you to then only allow requests from uncorrupted devices.
By combining App Check and Security Rules you get both broad protection from abuse, and fine-grained control over the data structure and who can access what data.

Store client-side data, making it available to a service worker

In my node.js chat app, I want to save chat data in offline mode and push notification when online. Basic chat app is done. I'm using ws node module for server code. In client side code, I want to use service worker for storing offline data. I have done some home work https://jakearchibald.com/2014/offline-cookbook/ https://ole.michelsen.dk/blog/making-an-offline-webapp-with-service-workers.html, but I think I don't understand how can I store chat data in service worker offline data.
IndexedDB is a general purpose database that's available client-side in both the service worker and main web page context. I'd suggest using that to store data like chat messages.
There are a number of libraries out there that wrap IndexedDB to make the interface friendlier. A relatively newer one, idb, has the advantage of providing a promise-based interface, which comes in handy when using IndexedDB from a service worker, since so much of the asynchronous code there is already promise-based.
Once I also have to faced that type of problem. So what I do, is some kind of cheating. I create an object in IndexedDB where I store every chat data temporally and after successfully send my chat data to server, I immediately delete my IndexedDB data. If chat data failed to send to server, it cannot delete temporally IndexedDB data. And when server is available to receive chat data, first check IndexedDB data and send to saved chat data (if any left).
NB: this is not accurate solution, not even close.

Share constants between iOS client code and Parse cloud code

I have an iOS app that uses Parse as backend. There, some cloud code is executed.
Both have to share the same constants.
I can share these constants on the client side via obj-c #import, and I can share it on the cloud code side via module.exports / require.
But how can I share it between client code and cloud code? It is simply error prone to define the same constants twice.
Parse offers a config object that can be queried like a class (returning an NSDictionary in iOS). Moreover, it can be configured via the web UI at parse.com. See docs here.
Upon startup, your app can retrieve the config and cache it locally. You may choose to cache it semi-permanently (say, with NSUserDefaults) and then use local copy indefinitely. I usually opt for some fixed expiration period (like weekly, so my constants are not-quite constant). Start up logic is, if the interval between now and my last config fetch exceeds the week, fetch again and replace.

Monitor Network Calls IOS using Restkit

I am completely dependent on Rest Kit for my app for network calls. I want to see the logs of how much
1) Time taken by each API to get a response
2) Size of Request/Response Payload
3) URL of the API
Is there any way I can enable such logging in Restkit. My app is calling like 50-60 API an dI don't want to dig into entire code base an add manual logs. Also I don't want to use network profiling tool since I will be tracking this data when an actual user is using the application.
Cant also use any third party paid tool so want to log these values in application database.
RestKit does have a log you can enable, but that isn't what you want to do if you plan to actually release this. It also writes to the log, not a value you can actually process and save.
Your likely best option is to subclass the RKObjectManager and intercept the requests that are being placed and the NSURLRequests which are being generated.

RestKit automatically POST/PUT when back online

Our app supports offline activity. Meaning we want to persist locally the creation of new core data objects as well as any modifications on existing objects. Then when the app goes online again we automatically push those changes (and any dependencies) up to the server.
I would think that RestKit would support such an operation, but currently when offline we store creations/modifications in a local cache. If I kill the app, those changes are not persisted. And also there is no attempt by RestKit to post those items to their originally intended endpoints.
I cannot find any documentation to support what we need here.
Is there a way for RestKit to do what we need?
If not, how do I get offline changes to persist to the disk (and not cache)? Then would it be appropriate to flag those as not uploaded to server, and then try uploading them when we are back online?
Any other important things I should consider?
At the time of writing RestKit does not support that feature.
To save to disk you need to call saveToPersistentStore: instead of just save: on the MOC.
You need to implement a scheme yourself, observing the 'online' status of the app and scanning the data store for things that need to be uploaded (which means maintaining a flag to indicate if it's happened yet).
I solved this issue by adding another field called 'updated' to my object. This field is set to true or 1 when the object is created or modified. Each time the application is started or synchronized, it iterates through the local core data copy and sends the objects with 'updated' set. On the web service, the response ALWAYS clears 'updated' to false when returning a response. This works well in the case where the web service and app are both online.

Resources