Skip to content

Commit

Permalink
Add unstructured data example (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
rorbech committed Jun 4, 2024
1 parent be26dc9 commit 1c083c4
Show file tree
Hide file tree
Showing 32 changed files with 456 additions and 4 deletions.
6 changes: 5 additions & 1 deletion AppServicesUsageSamples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ This sample demonstrates user presence detection with App Services.

A showcase for the different client reset resolution strategies with an sync error handling example.

### [Modelling unstructured data](apps/dynamic-data/README.md)

A showcase for storing and synchronizing unstructured data through collections in mixed properties.

## Demo app structure

The project has been structured in two main folders:
Expand Down Expand Up @@ -52,4 +56,4 @@ The `realm-cli import` command will prompt for the app configuration details, th

After deploying the Atlas apps, you will need to update [Constants.kt](demo/src/main/java/io/realm/appservicesusagesamples/Constants.kt) with their app ids.

Once you have completed these steps, you would be able to run the samples using the Kotlin demo app.
Once you have completed these steps, you would be able to run the samples using the Kotlin demo app.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions AppServicesUsageSamples/apps/dynamic-data/.mdb/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"config_version": 20230101,
"app_id": "6655920fc1ed444018db297b",
"group_id": "64c37d22e47344686a325451",
"client_app_id": "dynamic-data-fmzmcph",
"last_pulled": 1717066261
}
15 changes: 15 additions & 0 deletions AppServicesUsageSamples/apps/dynamic-data/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Dynamic data

With the newly added ability to store collections in mixed properties, you can now store and synchronized
data without pre-known schema.

This app just holds a single data class that mixes strictly typed properties and a single mixed property
that will be used as an entry point for the potentially deeply nested, dynamic data.

The Kotlin UI shows each entity and associated 'configuration' mixed property in a tree view. There is
currently no update options in the UI, so data has to be added through the Atlas UI in the
"Data Service" section:

![alt text](../../Screenshots/dynamic-data-browser.png "Atlas collection browser")

Updates will be reflected in the Kotlin UI.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"enabled": false
}
12 changes: 12 additions & 0 deletions AppServicesUsageSamples/apps/dynamic-data/auth/providers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"anon-user": {
"name": "anon-user",
"type": "anon-user",
"disabled": false
},
"api-key": {
"name": "api-key",
"type": "api-key",
"disabled": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "mongodb-atlas",
"type": "mongodb-atlas",
"config": {
"clusterName": "Cluster0",
"readPreference": "primary",
"wireProtocolEnabled": false
},
"version": 1
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"roles": [
{
"name": "readAndWriteAll",
"apply_when": {},
"document_filters": {
"read": true,
"write": true
},
"insert": true,
"delete": true,
"search": true,
"read": true,
"write": true
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"title": "DynamicDataEntity",
"type": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"configuration": {
"bsonType": "mixed"
},
"name": {
"bsonType": "string"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"values": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"values": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"values": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"values": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"values": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
4 changes: 4 additions & 0 deletions AppServicesUsageSamples/apps/dynamic-data/graphql/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"use_natural_pluralization": true,
"disable_schema_introspection": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"read_validation_action": "ERROR",
"read_validation_level": "STRICT",
"write_validation_action": "ERROR",
"write_validation_level": "STRICT"
}
3 changes: 3 additions & 0 deletions AppServicesUsageSamples/apps/dynamic-data/hosting/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"enabled": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
5 changes: 5 additions & 0 deletions AppServicesUsageSamples/apps/dynamic-data/root_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "dynamic-data",
"provider_region": "aws-eu-central-1",
"deployment_model": "LOCAL"
}
9 changes: 9 additions & 0 deletions AppServicesUsageSamples/apps/dynamic-data/sync/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"type": "flexible",
"state": "enabled",
"development_mode_enabled": true,
"service_name": "mongodb-atlas",
"database_name": "dynamic_data",
"client_max_offline_days": 30,
"is_recovery_mode_disabled": false
}
8 changes: 6 additions & 2 deletions AppServicesUsageSamples/demo/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ plugins {
// alias(libs.plugins.realm.kotlin)
id(libs.plugins.realm.kotlin.get().pluginId)
alias(libs.plugins.kotlin.serialization)
// alias(libs.plugins.jetbrainsCompose)
alias(libs.plugins.jetbrainsCompose)
alias(libs.plugins.compose.compiler)
}

android {
namespace = "io.realm.appservicesusagesamples"
compileSdk = 33
compileSdk = 34

defaultConfig {
applicationId = "io.realm.appservicesusagesamples"
Expand Down Expand Up @@ -76,6 +76,10 @@ dependencies {
implementation(libs.koin.android)
implementation(libs.koin.androidx.compose)

implementation(libs.bonsai)
// Compile only dependency of libs.bonsai, so need to include it explicitly
implementation(compose.materialIconsExtended)

implementation(libs.realm.library.sync)

debugImplementation(composeBom)
Expand Down
3 changes: 2 additions & 1 deletion AppServicesUsageSamples/demo/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<activity android:name=".propertyencryption.PropertyEncryptionActivity" android:launchMode="singleTop"/>
<activity android:name=".presence.PresenceDetectionActivity"/>
<activity android:name=".errorhandling.ErrorHandlingActivity"/>
<activity android:name=".dynamicdata.DynamicDataActivity"/>
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.realm.appservicesusagesamples

import android.app.Application
import io.realm.appservicesusagesamples.dynamicdata.dynamicDataViewModel
import io.realm.appservicesusagesamples.errorhandling.errorHandlingModule
import io.realm.appservicesusagesamples.propertyencryption.propertyEncryptionModule
import io.realm.appservicesusagesamples.presence.presenceDetectionModule
Expand All @@ -42,6 +43,7 @@ class AppServicesUsageSamplesApp: Application() {
propertyEncryptionModule,
presenceDetectionModule,
errorHandlingModule,
dynamicDataViewModel,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ package io.realm.appservicesusagesamples
const val PROPERTY_ENCRYPTION_APP_ID = "<insert-app-id>"
const val USER_PRESENCE_APP_ID = "<insert-app-id>"
const val ERROR_HANDLING_APP_ID = "<insert-app-id>"
const val DYNAMIC_DATA_APP_ID = "<insert-app-id>"
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
*/
package io.realm.appservicesusagesamples

import io.realm.appservicesusagesamples.dynamicdata.DynamicDataActivity
import io.realm.appservicesusagesamples.propertyencryption.PropertyEncryptionActivity
import io.realm.appservicesusagesamples.ui.SampleSelectorScreenViewModel
import io.realm.appservicesusagesamples.presence.PresenceDetectionActivity
import io.realm.appservicesusagesamples.ui.EntryView
import io.realm.appservicesusagesamples.ui.buttonSelector
import io.realm.appservicesusagesamples.ui.errorHandlingSelector
import io.realm.kotlin.mongodb.App
import io.realm.kotlin.mongodb.AppConfiguration
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.qualifier.named
import org.koin.dsl.module
Expand Down Expand Up @@ -52,6 +54,13 @@ enum class Demos(
ERROR_HANDLING(
appId = ERROR_HANDLING_APP_ID,
addView = errorHandlingSelector,
),
DYNAMIC_DATA(
appId = DYNAMIC_DATA_APP_ID,
addView = buttonSelector(
"Dynamic data",
DynamicDataActivity::class.java,
)
);

val qualifier = named(appId)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2024 Realm Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http:https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.realm.appservicesusagesamples.dynamicdata

import io.realm.appservicesusagesamples.Demos
import io.realm.appservicesusagesamples.dynamicdata.ui.DynamicDataViewModel
import io.realm.appservicesusagesamples.presence.ui.UserStatusListViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module

val dynamicDataViewModel = module {
viewModel {
DynamicDataViewModel(
app = get(qualifier = Demos.DYNAMIC_DATA.qualifier),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2024 Realm Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http:https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.realm.appservicesusagesamples.dynamicdata

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import io.realm.appservicesusagesamples.dynamicdata.ui.DynamicDataScreen
import io.realm.appservicesusagesamples.dynamicdata.ui.DynamicDataViewModel
import io.realm.appservicesusagesamples.ui.theme.AppServicesUsageSamplesTheme
import org.koin.android.scope.AndroidScopeComponent
import org.koin.androidx.scope.activityRetainedScope
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.scope.Scope

/**
* Activity that hosts the views that would demo property level encryption.
*/
class DynamicDataActivity : ComponentActivity(), AndroidScopeComponent {
override val scope: Scope by activityRetainedScope()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: DynamicDataViewModel by viewModel()


setContent {
AppServicesUsageSamplesTheme {
DynamicDataScreen(
viewModel,
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2024 Realm Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http:https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.realm.appservicesusagesamples.dynamicdata.models

import io.realm.kotlin.types.RealmAny
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PersistedName
import io.realm.kotlin.types.annotations.PrimaryKey
import org.mongodb.kbson.BsonObjectId
import org.mongodb.kbson.ObjectId

class DynamicDataEntity: RealmObject {
@PersistedName("_id")
@PrimaryKey
var id: ObjectId = BsonObjectId()

var name: String = "<name>"

var configuration: RealmAny? = null
}
Loading

0 comments on commit 1c083c4

Please sign in to comment.