Realm Mobile Database Presentation

Download as pdf or txt
Download as pdf or txt
You are on page 1of 49

PERSISTING DATA WITH REALM MOBILE DATABASE

Adam Fisher
• Application Developer
Integrated Web & Mobile Solutions Team
CareSource
• Xamarin Certified Mobile Developer
• May 2015 – May 2016
• July 2017 – July 2018
@calmtuna
• Author of the Xamarin Forms Video Player component
@adamgfisher
• Worked with for 8 months in Chicago

• Currently working on the CareSource mobile app


/adamfisher
Outline
• Existing Mobile Persistence Solutions
• Benefits of a Mobile Database
• What is Realm?
• Code Examples
• Questions
Existing Persistence Solutions
KEY/VALUE STORAGE DATABASE STORAGE

• iOS: NSUserDefaults

• Android: SharedPreferences

• React Native: AsyncStorage

• Xamarin: Xamarin.Essentials
Realm SQLite
Object Oriented Database Relational Database

Cross-Platform Cross-Platform

Objects Tables, Indexes, Views

Remote Cloud Sync X


Built-in Encryption X
Live Objects X
await AsyncStorage.setItem(’ApplicationData',
'{ "data": [ { "id": 1, "name": "Bitcoin", "symbol": "BTC", "website_slug": "bitcoin" }, { "id": 2,
"name": "Litecoin", "symbol": "LTC", "website_slug": "litecoin" }, { "id": 3, "name": "Namecoin",
"symbol": "NMC", "website_slug": "namecoin" }, { "id": 4, "name": "Terracoin", "symbol": "TRC",
"website_slug": "terracoin" }, { "id": 5, "name": "Peercoin", "symbol": "PPC", "website_slug":
"peercoin" }, { "id": 6, "name": "Novacoin", "symbol": "NVC", "website_slug": "novacoin" }, { "id":
8, "name": "Feathercoin", "symbol": "FTC", "website_slug": "feathercoin" }, { "id": 9, "name":
"Mincoin", "symbol": "MNC", "website_slug": "mincoin" }, { "id": 10, "name": "Freicoin", "symbol":
"FRC", "website_slug": "freicoin" }, { "id": 13, "name": "Ixcoin", "symbol": "IXC", "website_slug":
"ixcoin" }, { "id": 14, "name": "BitBar", "symbol": "BTB", "website_slug": "bitbar" }, { "id": 16,
"name": "WorldCoin", "symbol": "WDC", "website_slug": "worldcoin" }, { "id": 18, "name":
"Digitalcoin", "symbol": "DGC", "website_slug": "digitalcoin" }, { "id": 25, "name": "GoldCoin",
"symbol": "GLD", "website_slug": "goldcoin" }, { "id": 31, "name": "Argentum", "symbol": "ARG",
"website_slug": "argentum" }, { "id": 32, "name": "Fastcoin", "symbol": "FST", "website_slug":
"fastcoin" }, { "id": 34, "name": "Bitgem", "symbol": "BTG", "website_slug": "bitgem" }, { "id": 35,
"name": "Phoenixcoin", "symbol": "PXC", "website_slug": "phoenixcoin" }, { "id": 37, "name":
"Megacoin", "symbol": "MEC", "website_slug": "megacoin" }, { "id": 41, "name": "Infinitecoin",
"symbol": "IFC", "website_slug": "infinitecoin" }, { "id": 42, "name": "Primecoin", "symbol": "XPM",
"website_slug": "primecoin" }, { "id": 43, "name": "Anoncoin", "symbol": "ANC", "website_slug":
"anoncoin" }, { "id": 45, "name": "CasinoCoin", "symbol": "CSC", "website_slug": "casinocoin" }, {
"id": 49, "name": "Bullion", "symbol": "CBX", "website_slug": "bullion" }, { "id": 50, "name":
"Emerald Crypto", "symbol": "EMD", "website_slug": "emerald" }, { "id": 51, "name": "GlobalCoin",
"symbol": "GLC", "website_slug": "globalcoin" }, { "id": 52, "name": "XRP", "symbol": "XRP",
"website_slug": "ripple" }, { "id": 53, "name": "Quark", "symbol": "QRK", "website_slug": "quark" },
{ "id": 56, "name": "Zetacoin", "symbol": "ZET", "website_slug": "zetacoin" }, { "id": 57, "name":
"SecureCoin", "symbol": "SRC", "website_slug": "securecoin" }, { "id": 58, "name": "Sexcoin",
"symbol": "SXC", "website_slug": "sexcoin" }, { "id": 61, "name": "TagCoin", "symbol": "TAG",
"website_slug": "tagcoin" }, { "id": 63, "name": "I0Coin", "symbol": "I0C", "website_slug": "i0coin"
}, { "id": 64, "name": "FlorinCoin", "symbol": "FLO", "website_slug": "florincoin" }, { "id": 66,
"name": "Nxt", "symbol": "NXT", "website_slug": "nxt" }, { "id": 67, "name": "Unobtanium", "symbol":
"UNO", "website_slug": "unobtanium" } ], "metadata": { "timestamp": 1532545712,
"num_cryptocurrencies": 66, "error": null } }');
Realm, Inc.
• Danish startup founded in 2011
• Native object oriented database
• Used to be called TightDB
What is a Realm?
• A Realm is a lightweight object container
that acts like a database
• Data can be queried, filtered,
interconnected, persisted
• Live/Reactive objects
• Can contain multiple types with schema
enforcement
Benefits of a database built for mobile
Offline-First Functionality Cross-Platform Apps
Make your app work as well offline Use the same database for all your
as it does online. apps, on any major platform.

Fast Queries Encryption


Even complex queries take Secure your data with transparent
nanoseconds, and stay up to date encryption and decryption.
with new data.

Reactive Architecture
Safe Threading Connect your UI to Realm, and
Access the same data concurrently
from multiple threads, with no data changes will appear
crashes. automatically.
Supported Platforms
Correlation
Realm Relational Database

Realm Database /Connection

Schema Table

Object Row

Object.Property Column
Realm
Studio
• Open and edit local
and synced Realms
• Administer any Realm
Object Server instance
• Available for Mac,
Windows, Linux
Supported Types (JavaScript)
Types Maps To

bool JavaScript Boolean values

int, float, double JavaScript number values


Internally int and double are stored as 64 bits while float is stored with 32 bits

string string

data ArrayBuffer

date Date
Query Language
• Inspired by NSPredicate
• Query Language:
https://realm.io/docs/javascript/latest/api/tutorial-query-language.html
• Cheat Sheet:
https://bit.ly/2nrwC7S
Format String
Summary
Basic
Comparisons
Basic
Compound
Predicates
String
Comparison
Operators
Aggregate
Operators
Unsupported
Operations
Unsupported
Operations
• Using OR OR OR instead of IN, results in repeatable code
Tips & Tricks and can be less efficient.
• When using REGEX and Matches, make sure they are the last
part of your predicate statement so it does less work.
• Write transactions have a non-negligible overhead; you
should try to minimize the number of write blocks within your
code.
Define the Objects in Your Schema
const PersonSchema = {
name: 'Person',
primaryKey: 'id',
properties: {
id: 'int', // primary key
firstName: 'string',
lastName: 'string'
}
};
Define the Objects in Your Schema
const CryptocurrencySchema = {
name: 'Cryptocurrency',
primaryKey: 'symbol',
properties: {
name: { type: 'string', indexed: true },
symbol: 'string',
price: 'double?',
marketCap: {type: 'int', default: 0},
founder: 'Person'
}
};
Define the Objects in Your Schema
const ExchangeSchema = {
name: 'Exchange',
primaryKey: 'name',
properties: {
name: 'string',
websiteUrl: 'string',
coins: 'Cryptocurrency[]',
}
};
Realm.open({schema: [PersonSchema, ExchangeSchema, CryptocurrencySchema]})
.then(realm => {
// Create Realm objects and write to local storage
realm.write(() => {
const bitcoin = realm.create('Cryptocurrency',
{ name: 'Bitcoin', symbol: 'BTC', price: 7500 });

bitcoin.price += 100; // Update a property value


});

// Query Realm for all coins with a high price


const coins = realm.objects('Cryptocurrency').filtered('price > 7500');

// Will return a Results object with our 1 coin


coins.length; // => 1

// Add another coin


realm.write(() => {
const eth = realm.create('Cryptocurrency',
{ name: 'Ethereum', symbol: 'ETH’, price: 7503.24});
});

// Query results are updated in real-time


coins.length // => 2

}) .catch(error => { console.log(error); });


Adding Objects
• Writes will block the thread they are made on.
• Reads are not blocked while a write is in progress.

try { realm.write(() => {


realm.create('Cryptocurrency', {name: 'Dogecoin', symbol: 'DOGE'});
});
} catch (e) {
console.log("Error on creation");
}
Updating Objects
• Writes will block the thread they are made on.
• You can update any object by setting its properties within a write transaction.

realm.write(() => { realm.write(() => {


dogecoin.price = 482.11; // Create a coin object
}); realm.create('Cryptocurrency', {
id: 1,
title: 'Primecoin',
symbol: 'XPM',
price: 541.32
});

// Update coin with new price keyed off the id


realm.create('Cryptocurrency',
{id: 1, price: 482.11}, true);
});
Deleting Objects
• Objects can be deleted by calling the delete method within a write transaction.

realm.write(() => {
// Create a coin object
let coin = realm.create(‘Cryptocurrency’,
{
title: 'Potcoin',
symbol: 'POT',
price: 77.45
});

// Delete the coin


realm.delete(coin);

// Delete multiple coins by passing in a `Results`, `List`,


// or JavaScript `Array`
let allCoins = realm.objects('Cryptocurrency');
realm.delete(allCoins); // Deletes all coins
});
To-One Relationships
For to-one relationships you specify the name property of the object schema you are
referencing as the property’s type:

const CryptocurrencySchema = {
name: 'Cryptocurrency',
primaryKey: 'symbol',
properties: {
// The following property definitions are equivalent
founder: {type: 'Person'},
founder: 'Person'
}
};
To-Many Relationships
const exchange = realm.objects('Exchange').filtered('name = "Coinbase "')[0];
let coins = createCoinObjects(); // <-- Not yet in Realm
// exchange.coins = coins; // <-- Error
coins = realm.copyToRealmOrUpdate(coins);
exchange.coins = coins; // <-- OK
Inverse Relationships
• Links to other objects are unidirectional.
• With LinkingObjects properties, you can obtain all objects that link to a given object from a
specific property.

const PersonSchema = {
name: 'Person',
properties: { exchangesOwned: 'Exchange[]' }
}
const ExchangeSchema = {
name: ‘Exchange',
properties: {
// No shorthand syntax for linkingObjects properties
founder: {type: 'linkingObjects', objectType: 'Person', property: 'exchangesOwned'}
}
}
Migrations
Realm.open({ schema: [PersonSchema, ExchangeSchema, CryptocurrencySchema],
schemaVersion: 1,
migration: (oldRealm, newRealm) => {
// only apply this change if upgrading to schemaVersion 1
if (oldRealm.schemaVersion < 1) {
const oldObjects = oldRealm.objects('Person');
const newObjects = newRealm.objects('Person');

// loop through all objects and set name property in the new schema
for (let i = 0; i < oldObjects.length; i++) {
newObjects[i].name =
oldObjects[i].firstName + ' ' + oldObjects[i].lastName;
}

}}}).then(realm => { const fullName = realm.objects('Person')[0].name;


});
Linear Migrations
const schemas = [
{ schema: schema1, schemaVersion: 1, migration: migrationFunction1 },
{ schema: schema2, schemaVersion: 2, migration: migrationFunction2 },
...
]

// the first schema to update to is the current schema version


// since the first schema in our array is at
let nextSchemaIndex = Realm.schemaVersion(Realm.defaultPath);

while (nextSchemaIndex < schemas.length) {


const migratedRealm = new Realm(schemas[nextSchemaIndex++]);
migratedRealm.close();
}

// open the Realm with the latest schema


Realm.open(schemas[schemas.length-1]);
Notifications
• Realm Notifications: simple callbacks notified when write
transactions are committed
• Collection Notifications: more sophisticated callbacks which
receive change metadata on insertions, deletions and updates
• Describes what changes have occurred at a fine-grained level
• Consists of object indices that were inserted/deleted/modified since last
notification
Realm Notifications
function updateUI() { // ... }
// Observe Realm Notifications
realm.addListener('change', updateUI);
// ..later remove the listener
realm.removeListener('change', updateUI);
// ..or unregister all listeners
realm.removeAllListeners();
Encryption
var key = new Int8Array(64);
// populate with a secure key
Realm.open({
schema: [PersonSchema, ExchangeSchema, CryptocurrencySchema],
encryptionKey: key
})
.then(realm => {
// Use the Realm as normal
var coins = realm.objects('Cryptocurrency');
});
Limitations
• NSData and String properties limited to 16 MB in size
• No auto-incrementing properties
• No Built-in mechanism for obsolescence and data cleaning
Resources for Learning More
• Realm.io – official website and documentation
• https://academy.realm.io – Realm Academy
• https://caster.io/courses/realm - video tutorials
• https://proandroiddev.com/realistic-realm-1-5-year-of-experience-
cef75c8b164e
• github.com/realm
• StackOverflow – use the [realm] tag to filter search
Questions

You might also like