You can simply the below 2 custom actions to send the OTP and update the phone number
1- Send OTP
// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/actions/actions.dart' as action_blocks;
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 the necessary package
import 'package:firebase_auth/firebase_auth.dart';
// Flag to track verification request status (optional)
bool isVerificationRequested = false;
Future<String?> sendOtp(String phoneNumber) async {
final auth = FirebaseAuth.instance;
if (!isVerificationRequested) {
isVerificationRequested = true;
String? verificationId;
void verificationCompleted(PhoneAuthCredential phoneAuthCredential) async {
// Verification logic can be implemented here if desired (optional)
print(
'Verification completed (handled in verifyOTP): ${phoneAuthCredential.verificationId}');
verificationId = phoneAuthCredential.verificationId;
}
try {
await auth.verifyPhoneNumber(
phoneNumber: phoneNumber,
verificationCompleted: verificationCompleted,
verificationFailed: (FirebaseAuthException error) =>
print('Verification failed: ${error.code}'),
codeSent: (verificationIdParam, resendToken) {
print('Code sent');
verificationId = verificationIdParam; // Save the verificationId
},
codeAutoRetrievalTimeout: (String verificationIdParam) {
verificationId =
verificationIdParam; // Handle automatic retrieval (optional)
},
);
} catch (error) {
print('Error sending OTP: $error');
return null; // Indicate error
} finally {
isVerificationRequested = false;
}
return verificationId; // Return verificationId if successful
} else {
print('Verification already requested. Please wait for the OTP.');
return null; // Indicate request already in progress (optional)
}
}
// Set your action name, define your arguments and return parameter,
// and then add the boilerplate code using the green button on the right!
2- Verify the OTP and update the current user phone number
// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/actions/actions.dart' as action_blocks;
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!
// Automatic FlutterFlow imports (usually remain unchanged)
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
// Define the updatePhoneNumber function
Future<void> updatePhoneNumber(PhoneAuthCredential phoneCredential) async {
// Get the current user
User? user = FirebaseAuth.instance.currentUser;
// Check if user is signed in
if (user != null) {
// Update the phone number
await user.updatePhoneNumber(phoneCredential);
} else {
// Handle the case when the user is not signed in
throw Exception("User is not signed in");
}
}
// Define a function to update the phone number of the current user in Firestore
Future<void> updatePhoneNumberInFirestore(String phoneNumber) async {
try {
// Get the current user
User? user = FirebaseAuth.instance.currentUser;
// Check if user is signed in
if (user != null) {
// Reference to the Firestore collection 'users' and the current user's document
CollectionReference users =
FirebaseFirestore.instance.collection('users');
DocumentReference userDocRef = users.doc(user.uid);
// Update the phone number field
await userDocRef.update({'phone_number': phoneNumber});
// Print a message indicating successful phone number update
print("Phone number update successful");
} else {
// Handle the case when the user is not signed in
throw Exception("User is not signed in");
}
} catch (e) {
// Handle any errors that occur during the update process
print("Error updating phone number: $e");
// You may choose to throw or handle this error differently based on your application's requirements
}
}
// Define the verifyAndUpdatePhoneNumber function
Future<bool> verifyOtpAndUpdatePhoneNumber(
String verificationId, String otpCode, String phoneNumber) async {
try {
// Create a PhoneAuthCredential using the verification ID and SMS code
PhoneAuthCredential phoneAuthCredential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: otpCode,
);
// Call the updatePhoneNumber function
await updatePhoneNumber(phoneAuthCredential);
await updatePhoneNumberInFirestore(phoneNumber);
// If verification and update are successful, return true
print("phone number changed successfully");
return true;
} catch (e) {
// If an error occurs during verification or update, return false
return false;
}
}
// Set your action name, define your arguments and return parameter,
// and then add the boilerplate code using the green button on the right!