Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ /

Manage Email/Password Users - Swift SDK

On this page

  • Register a New User Account
  • Confirm a New User's Email Address
  • Retry User Confirmation Methods
  • Resend a User Confirmation Email
  • Retry a User Confirmation Function
  • Reset a User's Password
  • Send a Password Reset Email
  • Run a Password Reset Function
  • Email/Password User Methods with Completion Handlers

When you have enabled the email/password provider in your Atlas App Services app, you can register a new account, confirm an email address, and reset a user's password from client code.

Changed in version 10.16.0: Email/password user APIs add async/await support. Code examples on this page updated to async/await syntax. For an example of the older syntax, see: Email/Password User Examples with Completion Handlers.

RLMApp *app = [RLMApp appWithId:YOUR_APP_ID];
RLMEmailPasswordAuth *client = [app emailPasswordAuth];
NSString *email = @"skroob2@example.com";
NSString *password = @"password12345";
[client registerUserWithEmail:email password:password completion:^(NSError *error) {
if (error != nil) {
NSLog(@"Failed to register: %@", [error localizedDescription]);
return;
}
// Registering just registers. You can now log in.
NSLog(@"Successfully registered user.");
}];
let app = App(id: YOUR_APP_SERVICES_APP_ID)
let client = app.emailPasswordAuth
let email = "skroob@example.com"
let password = "password12345"
do {
try await client.registerUser(email: email, password: password)
// Registering just registers. You can now log in.
print("Successfully registered user.")
} catch {
print("Failed to register: \(error.localizedDescription)")
}
RLMApp *app = [RLMApp appWithId:YOUR_APP_ID];
RLMEmailPasswordAuth *client = [app emailPasswordAuth];
// Token and tokenId are query parameters in the confirmation
// link sent in the confirmation email.
NSString *token = @"someToken";
NSString *tokenId = @"someTokenId";
[client confirmUser:token tokenId:tokenId completion:^(NSError *error) {
if (error != nil) {
NSLog(@"User confirmation failed: %@", [error localizedDescription]);
return;
}
// User confirmed
NSLog(@"Successfully confirmed user.");
}];
let app = App(id: YOUR_APP_SERVICES_APP_ID)
let client = app.emailPasswordAuth
// Token and tokenId are query parameters in the confirmation
// link sent in the confirmation email.
let token = "someToken"
let tokenId = "someTokenId"
do {
try await client.confirmUser(token, tokenId: tokenId)
// User email address confirmed.
print("Successfully confirmed user.")
} catch {
print("User confirmation failed: \(error.localizedDescription)")
}

The SDK provides methods to resend user confirmation emails or retry custom confirmation methods.

Resend a confirmation email. The confirmation tokens in each URL expire after 30 minutes. If a user does not follow the link and confirm within that period, they must request a new confirmation email.

let app = App(id: YOUR_APP_SERVICES_APP_ID)
let client = app.emailPasswordAuth
let email = "skroob@example.com"
// If Realm is set to send a confirmation email, we can
// send the confirmation email again here.
do {
try await client.resendConfirmationEmail(email)
// The confirmation email has been sent
// to the user again.
print("Confirmation email resent")
} catch {
print("Failed to resend confirmation email: \(error.localizedDescription)")
}

New in version 10.9.0.

Retry a custom user confirmation function.

let app = App(id: YOUR_APP_SERVICES_APP_ID)
let client = app.emailPasswordAuth
let email = "skroob@example.com"
// If Realm is set to run a custom confirmation function,
// we can trigger that function to run again here.
do {
try await client.retryCustomConfirmation(email)
// The custom confirmation function has been
// triggered to run again for the user.
print("Custom confirmation retriggered")
} catch {
print("Failed to retry custom confirmation: \(error.localizedDescription)")
}

Resetting a user's password is a multi-step process.

  1. In your client app, you provide a UI for the user to reset their password. Your App Services App can then send an email or run a custom function to confirm the user's identity.

  2. After confirming the user's identity, you can complete the password reset request.

  3. After the password reset is complete, the user can log in using the new password.

For more information about how to set your preferred password reset method, refer to the App Services Email/Password Authentication documentation.

To send password reset emails to confirm the user's identity, you must configure your App to send a password reset email.

To begin the password reset process, call sendResetPasswordEmail with the user's email. App Services sends an email to the user that contains a unique URL. The user must visit this URL within 30 minutes to confirm the reset.

After the user has visited the URL from the password reset email, call resetPassword with the user's email, the new password, and the token and tokenId provided in the unique URL.

If the user does not visit the URL from the password reset email within 30 minutes, the token and tokenId expire. You must begin the password reset process again.

RLMApp *app = [RLMApp appWithId:YOUR_APP_ID];
RLMEmailPasswordAuth *client = [app emailPasswordAuth];
// If Realm app password reset mode is "Send a password reset email",
// we can do so here:
NSString *email = @"forgot.my.password@example.com";
[client sendResetPasswordEmail:email completion:^(NSError *error) {
if (error != nil) {
NSLog(@"Failed to send reset password email: %@", [error localizedDescription]);
return;
}
// Email sent.
NSLog(@"Successfully sent reset password email.");
}];
// Later...
NSString *newPassword = @"mynewpassword12345";
// Token and tokenId are query parameters in the confirmation
// link sent in the reset password email.
NSString *token = @"someToken";
NSString *tokenId = @"someTokenId";
[client resetPasswordTo:newPassword token:token tokenId:tokenId completion:^(NSError *error) {
if (error != nil) {
NSLog(@"Failed to reset password: %@", [error localizedDescription]);
return;
}
// Password reset.
NSLog(@"Successfully reset password.");
}];
let app = App(id: YOUR_APP_SERVICES_APP_ID)
let client = app.emailPasswordAuth
let email = "forgot.my.password@example.com"
// If Realm app password reset mode is "Send a password reset email",
// we can do so here:
do {
try await client.sendResetPasswordEmail(email)
print("Password reset email sent.")
} catch {
print("Reset password email not sent: \(error.localizedDescription)")
}
// Later...
let newPassword = "mynewpassword12345"
// Token and tokenId are query parameters in the reset password
// link sent in the reset password email.
let token = "someToken"
let tokenId = "someTokenId"
do {
try await client.resetPassword(to: newPassword, token: token, tokenId: tokenId)
print("Password reset successful.")
} catch {
print("Failed to reset password: \(error.localizedDescription)")
}

When you configure your app to run a password reset function, you define the function that should run when you call callResetPasswordFunction() from the SDK. This function can take a username, a password, and any number of additional arguments. You can use these arguments to specify details like security question answers or other challenges that the user should pass to successfully complete a password reset.

You might prefer to use a custom password reset function when you want to define your own password reset flows. For example, you might send a custom password reset email from a specific domain. Or you might use a service other than email to confirm the user's identity.

On the App Services side, you define the custom password reset function that runs when you call this method. That function can return one of three possible statuses:

  • fail

  • pending

  • success

A fail status is treated as an error by the SDK. The SDK callResetPasswordFunction() does not take return values, so it does not return a pending or success status to the client.

Your App Services password reset function may return pending if you want the user to take some additional step to confirm their identity. However, that return value is not passed to the SDK's callResetPasswordFunction(), so your client app must implement its own logic to handle a pending status.

Your server-side function might send an email using a custom email provider. Or you may use SMS to confirm the user's identity via text message.

You have access to a token and tokenId in the App Services password reset function context. If you pass this information from your App Services password reset function, you can pass these values back to your app using universal links. Then, your client application can call resetPassword to complete the password reset flow.

let app = App(id: YOUR_APP_SERVICES_APP_ID)
let client = app.emailPasswordAuth
let email = "forgot.my.password@example.com"
let newPassword = "mynewpassword12345"
// The password reset function takes any number of
// arguments.
let args: [AnyBSON] = []
// This SDK call maps to the custom password reset
// function that you define in the backend. In this example,
// we assume your function waits for additional identity
// confirmation. Calling this function only kicks
// off the password reset function. It does not reset the password.
do {
try await client.callResetPasswordFunction(email: email, password: newPassword, args: args)
print("Successfully called the password reset function")
} catch {
print("Password reset failed: \(error.localizedDescription)")
}
// Later...
// Token and tokenId are parameters you can access
// in the App Services function context. You could send
// this to the user via email, SMS, or some other method.
let token = "someToken"
let tokenId = "someTokenId"
do {
try await client.resetPassword(to: newPassword, token: token, tokenId: tokenId)
print("Password reset successful.")
} catch {
print("Failed to reset password: \(error.localizedDescription)")
}

If your App Services password reset function does additional validation within the function, or if you have validated the user's identity prior to attempting to reset the password, you may configure the App Services function to return success. However, that return value is not passed to the SDK's callResetPasswordFunction(), so your client app must implement its own logic to handle a success status.

Calling the function in this example performs the entire password reset process.

let app = App(id: YOUR_APP_SERVICES_APP_ID)
let client = app.emailPasswordAuth
let email = "forgot.my.password@example.com"
let newPassword = "mynewpassword12345"
// The password reset function takes any number of
// arguments. You might ask the user to provide answers to
// security questions, for example, to verify the user
// should be able to complete the password reset.
let args: [AnyBSON] = []
// This SDK call maps to the custom password reset
// function that you define in the backend
do {
try await client.callResetPasswordFunction(email: email, password: newPassword, args: args)
print("Password reset successful!")
} catch {
print("Password reset failed: \(error.localizedDescription)")
}

If you're not using Apple's async/await syntax, all of these methods are available with completion handlers. This example shows registering a user with the completion handler syntax.

let app = App(id: YOUR_APP_SERVICES_APP_ID)
let client = app.emailPasswordAuth
let email = "skroob@example.com"
let password = "password12345"
client.registerUser(email: email, password: password) { (error) in
guard error == nil else {
print("Failed to register: \(error!.localizedDescription)")
return
}
// Registering just registers. You can now log in.
print("Successfully registered user.")
}

Back

User Metadata