@@ -171,7 +171,16 @@ class FirebasePhoneAuthController extends ChangeNotifier {
171171 /// If for any reason, the OTP is not send,
172172 /// [_onLoginFailed] is called with [FirebaseAuthException]
173173 /// object to handle the error.
174- Future <bool > sendOTP () async {
174+ ///
175+ /// [shouldAwaitCodeSend] can be used to await the OTP send.
176+ /// The firebase method completes early, and if [shouldAwaitCodeSend] is false,
177+ /// [sendOTP] will complete early, and the OTP will be sent in the background.
178+ /// Whereas, if [shouldAwaitCodeSend] is true, [sendOTP] will wait for the
179+ /// code send callback to be fired, and [sendOTP] will complete only after
180+ /// that callback is fired. Not applicable on web.
181+ Future <bool > sendOTP ({bool shouldAwaitCodeSend = true }) async {
182+ Completer ? codeSendCompleter;
183+
175184 codeSent = false ;
176185 await Future .delayed (Duration .zero, notifyListeners);
177186
@@ -180,7 +189,12 @@ class FirebasePhoneAuthController extends ChangeNotifier {
180189 }
181190
182191 verificationFailedCallback (FirebaseAuthException authException) {
183- _onLoginFailed? .call (authException, StackTrace .current);
192+ final stackTrace = authException.stackTrace ?? StackTrace .current;
193+
194+ if (codeSendCompleter != null && ! codeSendCompleter.isCompleted) {
195+ codeSendCompleter.completeError (authException, stackTrace);
196+ }
197+ _onLoginFailed? .call (authException, stackTrace);
184198 }
185199
186200 codeSentCallback (
@@ -191,6 +205,9 @@ class FirebasePhoneAuthController extends ChangeNotifier {
191205 _forceResendingToken = forceResendingToken;
192206 codeSent = true ;
193207 _onCodeSent? .call ();
208+ if (codeSendCompleter != null && ! codeSendCompleter.isCompleted) {
209+ codeSendCompleter.complete ();
210+ }
194211 _setTimer ();
195212 }
196213
@@ -208,6 +225,8 @@ class FirebasePhoneAuthController extends ChangeNotifier {
208225 _onCodeSent? .call ();
209226 _setTimer ();
210227 } else {
228+ codeSendCompleter = Completer ();
229+
211230 await _auth.verifyPhoneNumber (
212231 phoneNumber: _phoneNumber! ,
213232 verificationCompleted: verificationCompletedCallback,
@@ -217,13 +236,21 @@ class FirebasePhoneAuthController extends ChangeNotifier {
217236 timeout: _autoRetrievalTimeOutDuration,
218237 forceResendingToken: _forceResendingToken,
219238 );
239+
240+ if (shouldAwaitCodeSend) await codeSendCompleter.future;
220241 }
221242
222243 return true ;
223244 } on FirebaseAuthException catch (e, s) {
245+ if (codeSendCompleter != null && ! codeSendCompleter.isCompleted) {
246+ codeSendCompleter.completeError (e, s);
247+ }
224248 _onLoginFailed? .call (e, s);
225249 return false ;
226250 } catch (e, s) {
251+ if (codeSendCompleter != null && ! codeSendCompleter.isCompleted) {
252+ codeSendCompleter.completeError (e, s);
253+ }
227254 _onError? .call (e, s);
228255 return false ;
229256 }
@@ -322,9 +349,11 @@ class FirebasePhoneAuthController extends ChangeNotifier {
322349 _onError = null ;
323350 _onCodeSent = null ;
324351 _signOutOnSuccessfulVerification = false ;
325- _forceResendingToken = null ;
352+ // _forceResendingToken = null;
326353 _otpExpirationTimer? .cancel ();
327354 _otpExpirationTimer = null ;
355+ _otpAutoRetrievalTimer? .cancel ();
356+ _otpAutoRetrievalTimer = null ;
328357 _phoneNumber = null ;
329358 _linkWithExistingUser = false ;
330359 _autoRetrievalTimeOutDuration = kAutoRetrievalTimeOutDuration;
0 commit comments