Links

Add Email/Phone Verification

Most of the time, it's required for you to check if the user's identifier (their email or phone number) is valid. With Cotter, you can verify your users via email, SMS, or WhatsApp.

Step 1: Set Up Deep Linking

The verification will follow OAuth's PKCE flow which will open an in-app browser where your user can enter the OTP sent to their email/phone.
Pick a unique URL scheme for redirecting the user back to your app after the verification in the in-app browser is successful. For this example, we'll use myexample://auth_callback .
Setup in iOS
Add the following to your ios/Runner/Info.plist.
ios/Runner/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
​
<!-- ADD THE LINES FROM HERE -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>myexample</string> <!-- 👈 Change this to your own URL Scheme -->
<key>CFBundleURLSchemes</key>
<array>
<string>myexample</string> <!-- 👈 Change this to your own URL Scheme -->
</array>
</dict>
</array>
<!-- TO HERE -->
​
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
Setup in Android
Add the following to your android/app/src/main/AndroidManifest.xml.
android/app/src/main/AndroidManifest.xml
<manifest ...>
<application ...>
...
​
<!-- Add the lines from here -->
<activity android:name=".CallbackActivity" >
<intent-filter android:label="flutter_web_auth">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- 👇 This is for myexample://auth_callback -->
<data android:scheme="myexample" android:host="auth_callback"/>
</intent-filter>
</activity>
<!-- Until here -->
​
</application>
</manifest>
You may need to stop flutter-run and re-run it to see the changes.

Step 2: Update your Sign Up Function

Make sure you followed the guide for Sign In with Device. Update your Sign Up Function that you made on Step 2.
There are 2 ways to do this:

Option 1: Verifying Before Registering the User

This will work the following way:
  1. 1.
    The user will be asked to verify their email or phone number
  2. 2.
    If verification successful, we'll create a new User
  3. 3.
    Then, set up the current device as trusted.
Email
Phone (with Pre-built UI)
SMS
WhatsApp
// 2️⃣ Make Sign Up Function
void signUp(BuildContext context) async {
try {
// ❌ Remove this line
var user = await cotter.signUpWithDevice(identifier: inputController.text);
// ✅ Add the lines from here
// (1) Verify the user's email
// (2) Create the user if verification successful
var user = await cotter.signUpWithEmailOTP(
redirectURL: "myexample://auth_callback",
email: inputController.text,
);
// (3) Set up the current device as trusted
user = await user.registerDevice();
// To here
} catch (e) {
print(e);
}
}
// 2️⃣ Make Sign Up Function
void signUp(BuildContext context) async {
try {
// ❌ Remove this line
var user = await cotter.signUpWithDevice(identifier: inputController.text);
// ✅ Add the lines from here
// (1) Verify the user's phone
// (2) Create the user if verification successful
var user = await cotter.signUpWithPhoneOTP(
redirectURL: "myexample://auth_callback",
channels: [PhoneChannel.SMS, PhoneChannel.WHATSAPP], // optional, default is SMS
);
// (3) Set up the current device as trusted
user = await user.registerDevice();
// To here
} catch (e) {
print(e);
}
}
// 2️⃣ Make Sign Up Function
void signUp(BuildContext context) async {
try {
// ❌ Remove this line
var user = await cotter.signUpWithDevice(identifier: inputController.text);
// ✅ Add the lines from here
// (1) Verify the user's phone
// (2) Create the user if verification successful
var user = await cotter.signInWithPhoneOTPViaSMS(
redirectURL: "myexample://auth_callback",
phone: inputController.text,
);
// (3) Set up the current device as trusted
user = await user.registerDevice();
// To here
} catch (e) {
print(e);
}
}
// 2️⃣ Make Sign Up Function
void signUp(BuildContext context) async {
try {
// ❌ Remove this line
var user = await cotter.signUpWithDevice(identifier: inputController.text);
// ✅ Add the lines from here
// (1) Verify the user's phone
// (2) Create the user if verification successful
var user = await cotter.signInWithPhoneOTPViaWhatsApp(
redirectURL: "myexample://auth_callback",
phone: inputController.text,
);
// (3) Set up the current device as trusted
user = await user.registerDevice();
// To here
} catch (e) {
print(e);
}
}

Option 2: Verifying After Registering the User

This will work the following way:
  1. 1.
    The user will enter some identifier (email or phone number), and we'll create a new User with that unverified identifier.
  2. 2.
    Set up the current device as trusted.
  3. 3.
    Once the user is logged-in, ask the user to verify their email/phone number
Email
SMS
WhatsApp
// 2️⃣ Make Sign Up Function
void signUp(BuildContext context) async {
try {
var user = await cotter.signUpWithDevice(identifier: inputController.text);
// ✅ Add the line below
// (3) Verify the user's email
user = await user.verifyEmailWithOTP(redirectURL: "myexample://auth_callback");
} catch (e) {
print(e);
}
}
// 2️⃣ Make Sign Up Function
void signUp(BuildContext context) async {
try {
var user = await cotter.signUpWithDevice(identifier: inputController.text);
// ✅ Add the line below
// (3) Verify the user's phone
user = await user.verifyPhoneWithOTPViaSMS(redirectURL: "myexample://auth_callback");
​
} catch (e) {
print(e);
}
}
// 2️⃣ Make Sign Up Function
void signUp(BuildContext context) async {
try {
var user = await cotter.signUpWithDevice(identifier: inputController.text);
// ✅ Add the line below
// (3) Verify the user's phone
user = await user.verifyPhoneWithOTPViaWhatsApp(redirectURL: "myexample://auth_callback");
​
} catch (e) {
print(e);
}
}
Make sure that the identifier that you used inside cotter.signUpWithDevice has the correct type. (If the identifier is an email, then use verifyEmailWithOTP, and so on).

🎉 You're done!

You should now be able to enter your email or phone number during the signup process.