Navigation

Access Custom User Data

Overview

You can read arbitrary data about your application users, known as custom user data, directly within your ios application. For example, you might store a user’s preferred language, date of birth, or local timezone. To learn more about custom user data, see Enable Custom User Data.

Note

To use custom user data, you must Enable Custom User Data.

Read Custom User Data

You can read the custom user data of a currently logged in user through that user’s User object. You cannot edit custom user data through a User object. To edit custom user data, see Update Custom User Data. To read the data, access the customData property on the User object of a logged in user:

let appId = "<YourAppId>" // replace this with your App ID
let app = App(id: appId)
app.login(credentials: Credentials.anonymous()) { (user, error) in
    guard error == nil else {
        print("Failed to log in: \(error!.localizedDescription)")
        return
    }
    guard let user = user else {
        fatalError("User is nil without error")
    }

    // One way to use custom data:
    print("User custom data: \(user.customData)")

    // Another way: refresh in case the user data is stale.
    user.refreshCustomData() { (customData, error) in
        guard error == nil else {
            print("Failed to refresh custom data: \(error!.localizedDescription)")
            return
        } 
        guard let customData = customData else {
            // This may happen if no custom data was set for the user id.
            // It could also be caused by not having custom data enabled and
            // configured correctly!
            print("Custom data not set")
            return
        }
        // favoriteColor was set on the custom data.
        print("Favorite color: \(customData["favoriteColor"]!)")
    }
}
RLMApp *app = [RLMApp appWithId:@"<YourAppId>"]; // replace this with your App ID
[app loginWithCredential:[RLMCredentials anonymousCredentials] completion:^(RLMUser *user, NSError *error) {
    if (error != nil) {
        NSLog(@"Failed to log in: %@", error);
        return;
    }
    
    // One way to use custom data:
    NSLog(@"User custom data: %@", [user customData]);
    
    // Another way to use custom data: refresh in case the client-side data is stale
    [user refreshCustomDataWithCompletion:^(NSDictionary *customData, NSError *error) {
        if (error != nil) {
            NSLog(@"Failed to refresh custom user data: %@", error);
            return;
        }
        NSLog(@"Favorite color: %@", customData[@"favoriteColor"]);
    }];
}];

Custom Data May Be Stale

MongoDB Realm does not dynamically update the value of the client-side user custom data document immediately when underlying data changes. Instead, MongoDB Realm fetches the most recent version of custom user data whenever a user refreshes their access token, which is used by most SDK operations that contact the MongoDB Realm back end. Realm refreshes access tokens every 30 minutes, so custom user data can be stale for no more than 30 minutes.

Note

If you require the most recent version of custom user data, use the refreshCustomDataWithCompletion method to request the latest version of a user’s custom data.

Write Custom User Data

To create, update, or delete custom user data, you will need the following information from your app’s custom user data configuration:

You can find the name of the custom user data cluster in the the Custom User Data tab of the Users left sidebar entry of the Realm UI.

Create Custom User Data for a User

To create custom user data for a user, create a MongoDB document in the custom user data collection. The user ID field of the document should contain the the user’s user ID. The following example uses MongoDB Data Access to insert a document containing the user ID of the currently logged in user and a favoriteColor value into the custom user data collection:

let appId = "<YourAppId>" // replace this with your App ID
let app = App(id: appId)
app.login(credentials: Credentials.anonymous()) { (user, error) in
    guard error == nil else {
        print("Failed to log in: \(error!.localizedDescription)")
        return
    }
    guard let user = user else {
        fatalError("User is nil without error")
    }
    let client = user.mongoClient("mongodb-atlas")
    let database = client.database(named: "my_database")
    let collection = database.collection(withName: "users")

    // Insert the custom user data object
    collection.insertOne([
        "userId": AnyBSON(user.id!),
        "favoriteColor": "pink"
    ]) { (newObjectId, error) in
          guard error == nil else {
              print("Failed to insert document: \(error!.localizedDescription)")
              return
          }
          print("Inserted custom user data document with object ID: \(newObjectId!)")
    }
}
RLMApp *app = [RLMApp appWithId:@"<YourAppId>"]; // replace this with your App ID
[app loginWithCredential:[RLMCredentials anonymousCredentials] completion:^(RLMUser *user, NSError *error) {
    if (error != nil) {
        NSLog(@"Failed to log in: %@", error);
        return;
    }
    RLMMongoClient *client = [user mongoClientWithServiceName:@"mongodb-atlas"];
    RLMMongoDatabase *database = [client databaseWithName:@"my_database"];
    RLMMongoCollection *collection = [database collectionWithName:@"users"];
    [collection insertOneDocument:
        @{@"userId": [user identity], @"favoriteColor": @"pink"}
        completion:^(RLMObjectId *newObjectId, NSError *error) {
            if (error != nil) {
                NSLog(@"Failed to insert: %@", error);
            }
            NSLog(@"Inserted custom user data document with object ID: %@", newObjectId);
    }];
}];

You can add any number of arbitrary fields and values to the custom user data document when you create it. The user ID field is the only requirement for the document to become available on the User object as custom user data.

Update Custom User Data for a User

You can update custom user data using MongoDB Data Access, Realm Sync, MongoDB Compass, or the MongoDB Atlas Data Explorer.

To update a user’s custom user data with MongoDB Data Access, edit the MongoDB document whose user ID field contains the user ID of the user. The following example uses MongoDB Data Access to update the favoriteColor field of the the document containing the user ID of the currently logged in user in the custom user data collection:

let appId = "<YourAppId>" // replace this with your App ID
let app = App(id: appId)
app.login(credentials: Credentials.anonymous()) { (user, error) in
    guard error == nil else {
        print("Failed to log in: \(error!.localizedDescription)")
        return
    }
    guard let user = user else {
        fatalError("User is nil without error")
    }
    let client = user.mongoClient("mongodb-atlas")
    let database = client.database(named: "my_database")
    let collection = database.collection(withName: "users")
    collection.updateOneDocument(
        filter: ["userId": AnyBSON(user.id!)],
        update: ["favoriteColor": "cerulean"]
    ) { (updateResult, error) in
          guard error == nil else {
              print("Failed to update: \(error!.localizedDescription)")
              return
          }
          print("Matched: \(updateResult!.matchedCount), updated: \(updateResult!.modifiedCount)")
    }
}
RLMApp *app = [RLMApp appWithId:@"<YourAppId>"]; // replace this with your App ID
[app loginWithCredential:[RLMCredentials anonymousCredentials] completion:^(RLMUser *user, NSError *error) {
    if (error != nil) {
        NSLog(@"Failed to log in: %@", error);
        return;
    }
    RLMMongoClient *client = [user mongoClientWithServiceName:@"mongodb-atlas"];
    RLMMongoDatabase *database = [client databaseWithName:@"my_database"];
    RLMMongoCollection *collection = [database collectionWithName:@"users"];

    // Update the user's custom data document
    [collection updateOneDocumentWhere:@{@"userId": [user identity]}
        updateDocument: @{@"favoriteColor": @"cerulean"}
        completion:^(RLMUpdateResult *updateResult, NSError *error) { 
            if (error != nil) {
                NSLog(@"Failed to insert: %@", error);
            }
            NSLog(@"Matched: %lu, modified: %lu", [updateResult matchedCount], [updateResult modifiedCount]); 
    }];
}];

You can determine the id of a user through either the User object of the user once logged in or via the Users tab of the Users left sidebar entry of the Realm UI.

Summary

  • You can use custom user data to store arbitrary information about your application users.
  • MongoDB Realm stores custom user data as a document in a MongoDB collection determined by your application configuration.
  • MongoDB Realm associates custom user data with a user based on the value of the user ID field.
  • The custom user data field of the user object is read-only. You can modify custom user data using MongoDB Data Access or Sync.