Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More advanced ObjectServer example #6448

Open
wants to merge 10 commits into
base: cm/upgrade-gradle
Choose a base branch
from
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* Added better checks for detecting corrupted files, both before and after the file is written to disk.

### Fixed
* [ObjectServer] Native errors sometimes mapped to the wrong Java ErrorCode. [#6364](https://github.com/realm/realm-java/issues/6364)
* [ObjectServer] Native errors sometimes mapped to the wrong Java ErrorCode. (Issue [#6364](https://github.com/realm/realm-java/issues/6364), since 2.0.0)
* [ObjectServer] Query-based Sync queries involving LIMIT, limited the result before permissions were evaluated. This could sometimes result in the wrong number of elements being returned.
* Removed Java 8 bytecode. Resulted in errors like `D8: Invoke-customs are only supported starting with Android O (--min-api 26)` if not compiled with Java 8. (Issue [#6300](https://github.com/realm/realm-java/issues/6300), since 5.8.0).

Expand Down
25 changes: 16 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,23 @@ RUN cd /opt && \
rm -f android-tools-linux.zip

# Grab what's needed in the SDK
RUN mkdir "${ANDROID_HOME}/licenses" && \
echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "${ANDROID_HOME}/licenses/android-sdk-license"
RUN sdkmanager --update
# Accept all licenses
RUN yes y | sdkmanager --licenses
RUN sdkmanager 'platform-tools'
RUN sdkmanager 'build-tools;28.0.3'
RUN sdkmanager 'extras;android;m2repository'
RUN sdkmanager 'platforms;android-27'
RUN sdkmanager 'cmake;3.6.4111459'

# Accept licenses before installing components, no need to echo y for each component
# License is valid for all the standard components in versions installed from this file
# Non-standard components: MIPS system images, preview versions, GDK (Google Glass) and Android Google TV require separate licenses, not accepted there
RUN yes | sdkmanager --licenses

# SDKs
# Please keep these in descending order!
# The `yes` is for accepting all non-standard tool licenses.
# Please keep all sections in descending order!
RUN yes | sdkmanager \
'platform-tools' \
'build-tools;28.0.3' \
'extras;android;m2repository' \
'platforms;android-27' \
'cmake;3.6.4111459'

# Install the NDK
RUN mkdir /opt/android-ndk-tmp && \
Expand Down
1 change: 0 additions & 1 deletion dependencies.list
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,3 @@ ndkVersion=r10e
BUILD_INFO_EXTRACTOR_GRADLE=4.7.5
GRADLE_BINTRAY_PLUGIN=1.8.4


2 changes: 1 addition & 1 deletion examples/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
def projectDependencies = new Properties()
projectDependencies.load(new FileInputStream("${rootDir}/../dependencies.list"))
project.ext.sdkVersion = 27
project.ext.sdkVersion = 28
project.ext.minSdkVersion = 15
project.ext.buildTools = projectDependencies.get("ANDROID_BUILD_TOOLS")

Expand Down
2 changes: 1 addition & 1 deletion examples/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ android.enableD8=true
android.enableBuildScriptClasspathCheck=false

# See https://developer.android.com/studio/build/optimize-your-build#configuration_on_demand
org.gradle.configureondemand=false
org.gradle.configureondemand=false
45 changes: 45 additions & 0 deletions examples/objectServerActivityTrackerExample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Object Server Example

This project contains a demo app demonstrating how you can build a real world app using modern
Android components and frameworks together with Realm Sync.

This demo app covers the use case of managing people who have booked an activity during a vacation.

It makes it possible for the person in charge of the activity to handle checkins as well.


## Requirements

Two Query-based reference Realms must exist on the server. These must be called:

* `/demo1`
* `/demo2`

They can be created using an Admin user through Realm Studio.

## Build project

1) Edit `io.realm.examples.objectserver.activitytracker.Constants` and set the proper URL to the Realm Sync server
2) Compile and install the app `./gradlew clean installDebug`

## Technical Details

The app is built using the following frameworks/libraries:

* Kotlin 1.3
* Databinding
* Android Architecture Components: LiveData and ViewModel
* RxJava
* Realm Java

For the UI parts the project uses package-by-feature instead of package-by-layer, so e.g. everything
related to the Excursion selection screen should be in the `io.realm.examples.objectserver.activitytracker.ui.excursionlist`
package.

The project uses an MVVM architecture. All logic related to controlling the UI should be in the
various `*ViewModel` classes. These classes expose data using `LiveData` which are consumed by
the `Activity` using data binding.

As this demo is relatively simple in scope, all business logic are contained within the view model
classes, this also includes all usages of Realm.

55 changes: 55 additions & 0 deletions examples/objectServerActivityTrackerExample/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
buildscript {
ext.kotlin_version = '1.3.21'
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'

android {
compileSdkVersion rootProject.sdkVersion
buildToolsVersion rootProject.buildTools

defaultConfig {
applicationId 'io.realm.examples.objectserver.activitytracker'
targetSdkVersion rootProject.sdkVersion
minSdkVersion rootProject.minSdkVersion
versionCode 1
versionName "1.0"
}

dataBinding {
enabled = true
}
}

realm {
syncEnabled = true
}

def lifecycle_version = "2.0.0"
dependencies {
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

implementation 'io.reactivex.rxjava2:rxjava:2.2.4'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha03'

implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
}
2 changes: 2 additions & 0 deletions examples/objectServerActivityTrackerExample/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
android.enableJetifier=true
android.useAndroidX=true
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.realm.examples.objectserver.activitytracker">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:name="io.realm.examples.objectserver.activitytracker.MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".ui.login.LoginActivity"
android:label="@string/app_name"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.checkin.CheckinActivity"
android:label="@string/title_checkin" />
<activity
android:name=".ui.activitylist.SelectActivityActivity"
android:label="@string/title_select_activities" />
<activity
android:name=".ui.orderlist.OrdersActivity"
android:label="@string/title_orders" />
<activity android:name=".ui.bookingslist.BookingsListActivity" />
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2019 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://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.examples.objectserver.activitytracker

internal object Constants {
/**
* Realm Cloud Users:
* Replace INSTANCE_ADDRESS with the hostname of your cloud instance
* e.g., "mycoolapp.us1.cloud.realm.io"
*
* ROS On-Premises Users
* Replace the INSTANCE_ADDRESS with the fully qualified version of
* address of your ROS server, e.g.: INSTANCE_ADDRESS = "192.168.1.65:9080" and "http://" + INSTANCE_ADDRESS + "/auth"
* (remember to use 'http/realm' instead of 'https/realms' if you didn't setup SSL on ROS yet)
*/
private val INSTANCE_ADDRESS = "cmelchior.us1.cloud.realm.io"
val AUTH_URL = "https://$INSTANCE_ADDRESS/auth"
val STANDARD_REALM_URL = "realms://$INSTANCE_ADDRESS/demo1" // Query-based Realm
val ORDERS_REALM_URL = "realms://$INSTANCE_ADDRESS/demo2" // Query-based Realm

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2019 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://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.examples.objectserver.activitytracker

import android.app.Application
import io.realm.examples.objectserver.activitytracker.model.App

import io.realm.Realm
import io.realm.SyncUser

class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Realm.init(this)

// Initialize the current Realm setup if a user is found
// This is required if we user should be allowed to
// start in the middle of the app after a crash.

// Make sure that calling Realm.getDefaultInstance() will throw
Realm.removeDefaultConfiguration()

SyncUser.current()?.let {
App.configureRealms(it)
}
}
}