RealmFire's aim is to automatically sync a local realm database with firebase.
NOTE! This is an inofficial library which currently is nothing more then a proof of concept. Feel free to post issues if you have any feedback or let me know that you aim to use it and for what.
The library offers similar functionality as the Realm Mobile Platform which is the official realm sync solution and is the better choice in most cases. RealmFire is useful when you are already invested in firebase or if you are developing a service for platforms not supported by Realm Mobile Platform such as the web.
The advantage of using realm, and not only the firebase sdk, is that you get an offline first application. It will sync data when network is available, but it can handle months without any connection if necessary.
- Download the repository and add the RealmFire folder to your project (package manager support is WIP, see #1)
- Extend
SyncObject
instead ofObject
to map that class to a firebase collection - After updating a realm object, call
RealmFire.markForSync(object)
orRealmFire.markForDeletion(object)
in a write transaction to sync that object the next sync. - Call
RealmFire.sync()
to sync. This will both fetch changes from firebase and upload local changes.
Only tested with Swift 3
, RealmSwift 2.4.2
and Firebase SDK 3.12.0
Below is a minimal usage example. Take a look at the the demo project for more details.
// Person.swift
class Person: SyncObject {
dynamic var name = ""
dynamic var age = 0
}
// ViewController.swift
let realm = try! Realm()
try! realm.write {
let person = realm.create(Person.self)
person.name = "John"
person.age = 25
RealmFire.markForSync(person)
}
// The sync call attempts to sync all changed objects and fetch changed firebase objects
RealmFire.sync(realm, firDatabase)
The main class containing all public api methods
RealmFire.sync()
Uploads local changes and fetches firebase updatesRealmFire.markForSync(objects)
Adds the specifiedSyncObjects
to the sync queue.RealmFire.markForDeletion(objects)
Adds the specifiedSyncObjects
to the deletion queue.
A SyncObject
is an Object
which maps to a specific firebase collection.
primaryKey()
The primary key of a realm object will also be used as primary key for the firebase collection. Required to be overriden bySyncObject
subclasses.collectionName()
Override to specify a custom firebase collection name. Default is the class name.customAttributes()
Override to specify custom attribute name mappings between firebase and realm.encode(prop: Property)
anddecode(prop: Property)
Override for customized object encoding/decodinguploadedAtAttribute()
Override to rename the attribute which the library uses to query only changed objects
The default behavior of RealmFire is to silently ignore errors. If you want to show the user that an error occured you can set a custom error reporter with RealmFire.setErrorHandler()
.
This library automatically resolves sync conflicts with a best guess attitude. Currently this means that the object which is last sent to firebase will always win. There are plans to implement a somewhat better sync strategy based on when objects were modified, see #2.
RealmFire handles deletions by adding a deleted_at flag to each object and then syncing this to clients.
- Change
SyncMeta
to dictionary based - Sync deletions from firebase to realm (force soft delete?)
- Write inline code comments for design descisions
- Tests for
Syncer
- Tests for
Meta
- Make sure
Mapper
tests make sense
- Research how to add lib to cocoa pods, see complications here CocoaPods/CocoaPods#5368
- Make it possible to ask lib about syncing status
- Sync subsets of SyncObject classes to different firebsae apps
- Add way to not force user to create Object subclasses for readonly objects
- The idea is to use
Mapper
to convert between Dictionary and Object - Will probably be repressented by the Object subclass DataObject
- The idea is to use
- Wait to apply changes until all relationships are fetched (
udpatedAt
prop) - Consider helping user setup automatic sync
- Consider adding option for syncing when internet is back
I will most likely not merge any pull request until I have decided upon an initial design for the API. Feel free fork the library and use the code however you wish however.