Using FlutterFlow, Supabase, and OTP (One-Time Password) Authentication together can provide a powerful, secure, and scalable way to build mobile and web apps with user authentication. Let me explain why you might need to combine these three technologies:
OTP (One-Time Password) authentication is a secure and user-friendly way to verify users. Instead of remembering a password, users receive a time-sensitive code via email or SMS to log in or register.
Supabase is a backend service that helps you quickly set up essential backend components like databases, authentication, and real-time data syncing.
To set up your Supabase project, please follow the steps below:
1. Create a Supabase project
2. Enable Supabase Authentication
FlutterFlow is a low-code platform that makes it easy to build beautiful and functional apps quickly, without needing deep coding knowledge. It offers an intuitive drag-and-drop UI builder, integrations, and the ability to export the underlying Flutter code for more customization if needed.
To set up your Flutterflow project, please follow the steps below:
1. Create a Flutterflow project
Pages
Login Page : - User enters their email id and clicks Get OTP, which is sent to their email.
2. Enable Supabase Authentication in Flutterflow
In the phone OTP authentication we need to do one extra thing which was Twilio.
Twilio
Twilio is a cloud communications platform that enables developers to integrate various communication methods such as voice, video, messaging, and email into their applications. Twilio provides APIs and tools that make it easy to build communication functionality into mobile apps, web applications, or even hardware devices.
To set up your Twilio account, please follow the steps below:
Twilio Account setup
Create a sign Up With Phone custom action
// Automatic FlutterFlow imports
import '/backend/supabase/supabase.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'package:supabase_flutter/supabase_flutter.dart';
Future<String?> signUpWithPhone(
String phone,
String password,
String confirmPassword,
) async {
// Add your function code here!
// Get a reference your Supabase client
final supabase = Supabase.instance.client;
if (confirmPassword == password) {
try {
await supabase.auth.signUp(
phone: phone,
password: password,
);
return (null);
} on AuthException catch (e) {
return (e.message);
}
} else {
return ('Passwords do not match. Please try again.');
}
}
// Automatic FlutterFlow imports
import '/backend/supabase/supabase.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'package:supabase_flutter/supabase_flutter.dart';
Future getPhoneOtp(String phone) async {
// Add your function code here!
// Get a reference your Supabase client
final supabase = Supabase.instance.client;
await supabase.auth.signInWithOtp(
phone: phone,
shouldCreateUser: false,
);
}
// Automatic FlutterFlow imports
import '/backend/supabase/supabase.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'package:supabase_flutter/supabase_flutter.dart';
Future<bool> confirmPhoneOtp(String token, String phone) async {
// Add your function code here!
// Get a reference your Supabase client
final supabase = Supabase.instance.client;
try {
await supabase.auth.verifyOTP(
type: OtpType.sms,
token: token,
phone: phone,
);
return true;
} catch (error) {
return false;
}
}
Create a Check for Authentication custom action
// Automatic FlutterFlow imports
import '/backend/supabase/supabase.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'package:supabase_flutter/supabase_flutter.dart';
Future<bool> checkAuth() async {
// Add your function code here!
// Get a reference your Supabase client
final supabase = Supabase.instance.client;
final Session? session = supabase.auth.currentSession;
if (session != null) {
print('Signed In!');
return true;
} else {
print('No sign in');
return false;
}
}
Note :
Through that OTP was send to the admins registered Number Because through trial account you cannot send messages to the unverified numbers. To send OTP for login to every unverified numbers you need to purchase a Twilio number to send messages to unverified numbers also.
Mobile OTP authentication with Supabase in FlutterFlow combines simplicity, security, and scalability, making it an ideal solution for modern applications. It caters to mobile-first users while leveraging the best practices in authentication, allowing developers to deliver a secure and seamless user experience.