Stream Data to Atlas - Kotlin SDK
On this page
New in version 1.10.0.
If you have a mobile or client application that produces a large volume of data you'd like to stream to MongoDB Atlas, you can sync data unidirectionally using Device Sync. We call the feature that enables this unidirectional sync Data Ingest.
You can use Data Ingest to stream data from the client application to a Flexible Sync-enabled Atlas App Services App.
You might want to sync data unidirectionally in IoT applications, such as a weather sensor sending data to the cloud. Data Ingest is also useful for writing other types of immutable data where you do not require conflict resolution, such as creating invoices from a retail app or logging application events.
Data Ingest is optimized to provide performance improvements for heavy client-side insert-only workloads.
Data Ingest requires Flexible Sync.
Asymmetric Objects
The Kotlin SDK provides a special type of Realm object to use with Data Ingest: an asymmetric object.
Asymmetric objects broadly support the same property types as RealmObject
,
with a few exceptions:
Asymmetric objects can only be used in synced realms configured with Flexible Sync. However, you cannot create subscriptions to asymmetric objects.
An
AsymmetricRealmObject
can containEmbeddedRealmObject
types, but cannot containRealmObject
types or otherAsymmetricRealmObject
types.AsymmetricRealmObject
types cannot be used as properties in other Realm objects.
Additionally, asymmetric objects do not function in the same way as other Realm objects. You cannot add, read, update, or delete an asymmetric object from the realm. You can only create an asymmetric object, which then syncs unidirectionally to the Atlas database linked to your App with Device Sync. Realm then deletes this object after syncing.
Tip
Asymmetric and Non-Asymmetric Objects in the Same Realm
The Kotlin SDK allows you to work with asymmetric objects
and non-asymmetric Realm objects (RealmObject
and
EmbeddedRealmObject
types) within the same realm. Include all
objects in the Sync configuration when you open the realm.
However, you cannot subscribe to the asymmetric objects.
Sync Data Unidirectionally from a Client Application
Define an Asymmetric Object
You can sync data unidirectionally when that object is an AsymmetricRealmObject
.
Define an asymmetric object by implementing the AsymmetricRealmObject interface:
// Implements the `AsymmetricRealmObject` interface class WeatherSensor : AsymmetricRealmObject { var id: ObjectId = ObjectId() var deviceId: String = "" var temperatureInFarenheit: Float = 0.0F var barometricPressureInHg: Float = 0.0F var windSpeedInMph: Int = 0 }
Connect and Authenticate with an App Services App
To stream data from the client to your backend App, you must connect to an App Services backend and authenticate a user.
val app = App.create(YOUR_APP_ID) val user = app.login(credentials)
Data Ingest is a feature of Flexible Sync, so the App you connect to must use Flexible Sync.
Open a Realm
After you have an authenticated user, you can open a synced realm
using a SyncConfiguration.
Specify the AsymmetricRealmObject
types you want to sync.
val config = SyncConfiguration.create(user, setOf(WeatherSensor::class)) val realm = Realm.open(config) Log.v("Successfully opened realm: ${realm.configuration.name}")
Unlike bi-directional Sync, Data Ingest does not use a Flexible Sync subscription. If you have non-asymmetric objects in the same realm, you can add a Flexible Sync subscription query for only those objects.
Create Asymmetric Objects
Once you have an open Realm, you can create an AsymmetricRealmObject
inside
a write transaction using the insert()
extension method:
// Open a write transaction realm.write { // Create a new asymmetric object val weatherSensor = WeatherSensor().apply { deviceId = "WX1278UIT" temperatureInFarenheit = 6.7F barometricPressureInHg = 29.65F windSpeedInMph = 2 } // Insert the object into the realm with the insert() extension method insert(weatherSensor) // WeatherSensor object is inserted into the realm, then synced to the // App Services backend. You CANNOT access the object locally because it's // deleted from the local realm after sync is complete. }
You cannot read these objects. Once created, they sync to the App Services backend and the linked Atlas database.
Atlas Device Sync completely manages the lifecycle of this data. It is maintained on the device until Data Ingest synchronization is complete, and then removed from the device.