- run this command in terminal to get SHA1 & SHA256, before run this command you must in .android directory
keytool -list -v -keystore "debug.keystore" -alias androiddebugkey -storepass android -keypass android
- create firebase project
- add new app, insert your package name, App name, and SHA-1

- follow the instruction to finish the setup firebase for android
- Click authentication, add new provider, enable phone to authentication using phone number


- add this package to pubspec.yaml
# this package is use to get country code from all coutry
country_picker: ^2.0.21
# this package is use to authentication using firebase
firebase_core: ^2.17.0
firebase_auth: ^4.10.1
- add this code to main method in main.dart file
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform)
.then((value) => null);
- add this code to get country phone code and to select other country
// add this code outside widget build
Country selectedCounty = Country(
phoneCode: '62',
countryCode: 'ID',
e164Sc: 0,
geographic: true,
level: 1,
name: 'Indonesia',
example: 'Indonesia',
displayName: 'Indonesia',
displayNameNoCountryCode: 'ID',
e164Key: '',
);
// add this inside scaffold widget
TextFormField(
cursorColor: Colors.purple,
controller: phoneController,
decoration: InputDecoration(
hintText: 'Enter Phone Number',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.black12),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.black12),
),
prefixIcon: Container(
padding: const EdgeInsets.all(8),
child: InkWell(
onTap: () {
showCountryPicker(
context: context,
countryListTheme: CountryListThemeData(
bottomSheetHeight:
MediaQuery.of(context).size.height * 0.6,
),
onSelect: (value) {
selectedCounty = value;
},
);
},
child: Text(
'${selectedCounty.flagEmoji} + ${selectedCounty.phoneCode}',
style: const TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.bold),
),
),
),
),
),
- add this code to your state management file, this code is used to sign in using phone number and to get otp code messages
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
// phone number format => "+${selectedCounty.phoneCode}$phoneNumber"
Future<void> signInWithPhone(BuildContext context, String phoneNumber) async {
try {
await _firebaseAuth.verifyPhoneNumber(
phoneNumber: phoneNumber,
verificationCompleted: (PhoneAuthCredential phoneAuthCredential) async {
await _firebaseAuth.signInWithCredential(phoneAuthCredential);
},
verificationFailed: (error) {
throw Exception(error);
},
codeSent: (verificationId, forceResendingToken) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => OtpPage(verificationId: verificationId),
));
},
codeAutoRetrievalTimeout: (verificationId) {},
);
} on FirebaseAuthException catch (e) {
showSnackBar(context, e.message.toString());
}
}
- enable play integrity in app check product, insert SHA-256 you get before in this field and save

- add this package in pubspec.yaml to make otp field
pinput: ^3.0.1
- add this code in view to implement pinput package
Pinput(
length: 6,
showCursor: true,
defaultPinTheme: PinTheme(
width: 50,
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.purple),
),
textStyle: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
onCompleted: (value) {
setState(() {
otpCode = value;
});
print('OTP : $otpCode');
},
),
// add this code when you press button
if (otpCode!.isNotEmpty) {
verifyOtp(context, otpCode!);
} else {
showSnackBar(context, 'Enter 6-Digit code');
}
- add this code to your state management file, this code is used to verify your otp code
Future<void> verifyOtp({
required BuildContext context,
required String verificationId,
required String userOtp,
required Function onSuccess,
}) async {
_isLoading = true;
notifyListeners();
try {
PhoneAuthCredential credential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: userOtp,
);
User? user = (await _firebaseAuth.signInWithCredential(credential)).user!;
if (user != null) {
_uid = user.uid;
onSuccess();
// add this code in onSuccess function when you call verifyOtp in view
//ap.checkExistingUser().then((value) async {
// if (value == true) {
// } else {
// Navigator.pushAndRemoveUntil(
// context,
// MaterialPageRoute(
// builder: (context) => UserInformationPage(),
// ),
// (route) => false);
// }
// });
}
_isLoading = false;
notifyListeners();
} on FirebaseAuthException catch (e) {
showSnackBar(context, e.message.toString());
}
}
- For more details, see the video below