We just released a new version of Realm Java to this website and to Bintray. It contains a new wildcard query syntax as well as several improvements to the Realm Mobile Platform such as backup recovery and a more flexible data sharing and permission management system. Read on to learn more.
Flexible Data Sharing
Realtime collaboration and data sharing is an important pillar of the Realm Mobile Platform. To enable this, we made it possible for mobile developers to share Realms between users when we introduced the PermissionChange
APIs in November.
Today, we’re making it even easier to share Realms between users, allowing extremely flexible sharing and permission management, all controlled from the Realm client APIs and without the need to write any server code! Specifically, we’re adding the PermissionOffer
and PermissionOfferResponse
classes to allow creating and accepting permission change events for synchronized Realms between different users.
These APIs once again demonstrate the power of the Realm Mobile Platform’s objects-as-APIs approach. Making and receiving permission offers is very similar to the existing PermissionChange
process. Simply create the object in the current user’s management Realm and observe it to know when it was synchronized and processed by the Realm Object Server.
Sharing a synchronized Realm is as easy as following these steps:
- Create a
PermissionOffer
object in the user’s management Realm. - Wait for a notification that the token of the object is populated by the server. Once the
token
property of the object is populated, send it to another user however you’d like: push notification, email, carrier pigeon! - The receiving user then creates a
PermissionOfferResponse
object in his/her management Realm. - The receiving user then waits for the response to be synced and processed by the server.
- Once the response has been processed, the receiving user can now access the Realm at the response’s
realmUrl
property.
For example:
/**
* Sender
*/
SyncUser user = getUser("user");
Realm managementRealm = user.getManagementRealm();
String sharedRealmUrl = "realm://my.server/~/my-realm";
boolean mayRead = true;
boolean mayWrite = true;
boolean mayManage = true;
Date expiresAt = null; // Offer never expires;
final PermissionOffer offer = new PermissionOffer(sharedRealmUrl, mayRead, mayWrite, mayManage, expiresAt);
String offerId = offer.getId();
managementRealm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.insert(offer);
}
});
// Wait for server to handle the offer
RealmResults<PermissionOffer> offers = managementRealm.where(PermissionOffer.class)
.equalTo("id", offerId)
.equalTo("statusCode", 0)
.findAll();
offers.addChangeListener(new RealmChangeListener<RealmResults<PermissionOffer>>() {
@Override
public void onChange(RealmResults<PermissionOffer> offers) {
PermissionOffer offer = offers.first();
String token = offer.getToken();
// Offer is ready, send token to the other user
sendTokenToOtherUser(token);
}
});
/**
* Receiver
*/
final SyncUser user2 = getUser("user2");
Realm managementRealm = user.getManagementRealm();
// Accept the offer
String offerToken = getToken();
final PermissionOfferResponse offerResponse = new PermissionOfferResponse(offerToken);
managementRealm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.insert(offerResponse);
}
});
We have a Proof-Of-Concept branch towards RealmTasks that demonstrates how sharing lists between users could be built using this mechanism.
Backup Recovery
When your servers goes down, you need a plan to recover. That’s why the Realm Mobile Platform has offered the ability to back up your data for a few months now. Today we’re announcing our Continous Backup solution to automate keeping up-to-date backups.
Under normal conditions, Realm’s synchronization engine works by transferring just the specific operations. When the Realm Object Server confirms the receipt of new operations, the local logs are cleaned up. This helps keep your app’s disk usage small and Realm blazing fast ⚡️.
Furthermore, because Realm is an offline-first database, if your Realm Object Server is down for whatever reason, all your local data stays available.
However, if you need to recover from a backup on your server, your clients will receive a “client reset” error via the global error handler. Note that you may continue to use the local Realm as you normally would, but that any subsequent changes, or changes made after the last backup point, will be lost.
The next time your app launches, the previous local version of the Realm will be deleted and redownloaded from the server at the latest backed up version automatically on first access.
Wildcard Queries
Until now, the string query predicates have been limited to substring searches. With this release, we introduce the like
predicate which can do simple pattern matching. ?
will match a single-character while *
matches zero or more characters. For example
String[] names = {"Jim", "Simon", "Jimmy", "Tommy", "Jamie"};
realm.beginTransaction();
for (String name : names) {
Person person = realm.createObject(Person.class);
person.setName(name);
}
realm.commitTransaction();
RealmResults<Person> persons1 = realm.where(Person.class).like("name", "J?m*").findAll(); // => Jim, Jimmy, Jamie
RealmResults<Person> persons2 = realm.where(Person.class).like("name", "?im*").findAll(); // => Jim, Simon, Jimmy
Please read the API documentation to get the full picture on how to use like
.
Bug Fixes
- Fixed native memory leak setting the value of a primary key.
- Fixed “too many open files” issue.
- Activated Realm’s annotation processor on connectedTest when the project is using kapt.
Thanks for reading. Now go forth and build amazing apps with Realm! As always, we’re around on Stack Overflow, GitHub, or Twitter.
Receive news and updates from Realm straight to your inbox