Firebase A/B test offline behavior - firebase-remote-config

I am doing a Firebase A/B split-test with Remote Configs.
When a user is offline does he get the different variations from the config files?
How is this recorded in the analytics?

The initial default values are encoded in your application binary. Until you fetch updated values, the app will use these defaults. This includes if the app is unable to ever fetch updated values.
Once the app fetched values from the server, it stores those in local storage and uses those values next time it runs. So if your app is unable to fetch updated values afterwards, it uses the previous values that it fetched.
The app will always report its current values to Analytics, unless you explicitly log something else.

Related

Query Changes after receiving CKDatabaseNotification

I'm currently building an app that allows user to share events and check in their guests simultaneously using multiple phones. I managed to set up CKQuerySubscription and update, delete and create works fine but only on the primary phone (the one sharing the event).
I recently found out that for a non-primary user to get notifications, it has to get notifications from CKDatabaseNotification which i set up and it works as I am getting remote notifications when I make changes through CloudKit Dashboard.
But the notification i get (CKDatabaseNotification) does not come with anything that would allow me to find what records changed. I've tried casting it as CKNotification as suggested on this link but as expected it fails.
I have a custom zone set up and my questions are as below:
How do I get any information about what changed from a CKDatabaseNotification?
Am I even doing that the right way? I've read somewhere else as well that some people managed to set up subscription through CKQuerySubscription on a shared database as long as it is on a custom zone, which I have but my codes told me subscription failed.
The CKDatabaseNotification will only tell you that something has changed, not what it is. The recommended path forward is you use a CKFetchDatabaseChangesOperation to find out what record zones have changes. Then you use the record zone IDs from that operation in a CKFetchRecordZoneChangesOperation to get all the changes.
There's a bit more information in the CloudKit Quick Start Guide
I'm cherry picking some relevant info below:
After app launch or the receipt of a push, your app uses CKFetchDatabaseChangesOperation and then CKFetchRecordZoneChangesOperation to ask the server for only the changes since the last time it updated.
The key to these operations is the previousServerChangeToken object,
which tells the server when your app last spoke to the server,
allowing the server to return only the items that were changed since
that time.
First your app will use a CKFetchDatabaseChangesOperation to find out
which zones have changed
Then
Next your app uses a CKFetchRecordZoneChangesOperation object with the
set of zone IDs you just collected to do the following:
• Create and update any changed records
• Delete any records that no longer exist
• Update the zone change tokens
The WWDC video CloudKit Best Practices addresses this topic as well.

Are fetched, but not applied, values persisted across app launches in iOS Firebase remote config?

When using Firebase Remote Config with the iOS SDK, do values returned from remoteConfig.fetch() persist across app launches? The docs say that applied values are persisted:
If a value was fetched from the service and then activated, the app uses the fetched value. Activated parameter values are persistent.
Remote Config Docs
But I am interested if fetched values that have not been applied are persisted. I wasn't able to find any explicit documentation on that.
To clarify:
Call fetch() for new values, and wait for the call to return
Force quit app
Launch app
Call activateFetched()
Does my RemoteConfig now have the fetched values from the previous launch activated?
I've tested myself and seen that the values do persist across launches, but I don't want to be relying on undocumented behavior
Fetched values that are not applied are not ever used by the app. A call to apply must occur in order for previously fetched values to take effect. If never applied, then fetched values are never seen in the app, even across app restarts.
If you're asking that fetched values are stored persistently until applied, even across restarts, the answer to that is yes as well.

Realm Sync data resets on app reinstall

I have an iOS app which uses Realm locally and it works great, and my intention is to use Realm Object Server to enable:
Data sync across devices
Data restoration on app reinstall
I've been having a lot of trouble with the last one. The flow in my app is the following:
First, it tries to find a User in my Realm Sync. If a User exists, go to step 4. Otherwise, go to step 2;
Ask for the user's name, income and payday;
Get the user's userRecordID for iCloud and logIn to Realm Object Server.
Use the SyncUser's identity as the User entity identifier. Save the data I just asked (name, income and payday) to Realm;
Go to main app screen and let the user enjoy the app.
ROS is using cloudkit based authentication. The problem occurs if I follow steps 1-4 above, and then reinstall the app. I expected the previously created User to be retrieved in step 1, but instead all of its fields beside the primary key are set to blank values (name becomes empty string, income and payday become 0). Is this behavior expected? Is what I want to do within the purpose of Realm?
EDIT
Made the flow clearer after #AustinZ's answer.
"Data restoration on app install" is definitely a valid use case for Realm Sync. However, the flow you describe is problematic.
A synchronized Realm is identified by two pieces of information: a sync user and the Realm's path on the Realm Object Server (e.g. /~/my/realm). If you have the same sync user logged into multiple devices, and they each open a copy of a Realm at the same path, they are opening the same synced Realm and will stay in sync with each other.
However, to get the same sync user, a user needs to log in to the Realm Object Server from their device. You do this by creating a CloudKit SyncCredentials value using SyncCredentials.cloudKit(token:) and passing that credential to SyncUser.logIn(). The device will then communicate with the Realm Object Server, and if the log in succeeds, then the logIn() method's callback block will be invoked and will give you a SyncUser. That is the sync user you need to use to open Realms.
So:
You shouldn't be saving users or user info to Realms manually. We persist the relevant information automatically.
If a user deletes and re-installs their app, the app's documents and files are deleted as well, which means you shouldn't assume you can access a Realm's data after the app which created it was re-installed.
What you should be doing is, in step 3, using the user's CloudKit credentials and logging into the Realm Object Server as described above.
Please review our documentation for more information.

Find when Firebase data has been uploaded after coming back online

I am writing an Android/Cordova/Firebase app which needs to work offline. I have data objects which are updated; I simply update them and use Firebase Database's offline features so that they are uploaded when the app comes back online. That works fine. The problem is that the items also involve blobs which I need to upload to Firebase Storage. I want to somehow be alerted when a pending update is sent to the server, so that I can initiate the upload to Firebase Storage.
Of course I can manage the online/offline status myself with a queue of pending Firebase Storage uploads, but is there any way to have Firebase tell me when a pending update to the database has been made?
There is nothing built into the Firebase SDK to signal when it is completely in sync with the server. In the past I've recommended writing a dummy value from the client when it's back online and having a listener that wait for that dummy value to show up. Once you get that dummy value, you're guaranteed to have also received updates that were written before it.

How do I cache Firebase data for offline usage?

I build apps that bundle up JSON data. I want to switch to Firebase as my backend, but I need to ensure I can access the data even if firebase is offline. There's no guarantee that the user will have an internet connection at the time they launch the app. The data consists of a fairly large JSON blob.
I heard that firebase does cache data on iOS for offline access, and that's great. I just need to know how to bundle the data for that first time the app is ran, so the user can use the app prior to getting to a network connection.
As it sounds like you discovered, the Firebase Obj-C client does have beta support for offline access / disk persistence. Details can be found here.
But that doesn't address your desire to "seed" the app with initial data so that it has data available before the app has ever been able to connect to Firebase. Unfortunately, there's no direct support for that.
One hacky solution you could attempt with Firebase is to just do a setValue with the data in question, in order to seed the cache. This should work but will eventually try to write that data to Firebase, when the app gets connected, so you'd probably want to have security rules to prevent the user from actually modifying that data. As I said, it'd be a hacky solution.
For now it might be best to just handle this with special logic in your app that pulls data from some other data source (hardcoded values or an embedded file or whatever) until the first time you get data from Firebase.
Sorry there's no direct support for this at the moment. We'll take a look to see if we could support this more directly in the future.

Resources