Skip to content

Commit 3532257

Browse files
authored
Merge pull request #16 from rithik-dev/sendOtpOnInit
fixes
2 parents 2275420 + 2662ffd commit 3532257

7 files changed

Lines changed: 96 additions & 80 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## [1.0.8] - 20/01/2023
2+
3+
* Added sendOtpOnInitialize parameter to the handler
4+
* Fixed OTP resend issue if the OTP expiration timer is still active
5+
* Fixed #15
6+
* Added shouldAwaitCodeSend to the sendOTP fn to give more control over the function
7+
* Updated dependencies
8+
19
## [1.0.7] - 24/10/2022
210

311
* Stacktrace in onLoginFailed is now non-nullable

example/lib/screens/verify_phone_number_screen.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class _VerifyPhoneNumberScreenState extends State<VerifyPhoneNumberScreen>
6767
child: FirebasePhoneAuthHandler(
6868
phoneNumber: widget.phoneNumber,
6969
signOutOnSuccessfulVerification: false,
70+
sendOtpOnInitialize: true,
7071
linkWithExistingUser: false,
7172
autoRetrievalTimeOutDuration: const Duration(seconds: 60),
7273
otpExpirationDuration: const Duration(seconds: 60),

example/pubspec.lock

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ packages:
77
name: _flutterfire_internals
88
url: "https://pub.dartlang.org"
99
source: hosted
10-
version: "1.0.5"
10+
version: "1.0.12"
1111
async:
1212
dependency: transitive
1313
description:
1414
name: async
1515
url: "https://pub.dartlang.org"
1616
source: hosted
17-
version: "2.8.2"
17+
version: "2.9.0"
1818
boolean_selector:
1919
dependency: transitive
2020
description:
@@ -28,7 +28,7 @@ packages:
2828
name: characters
2929
url: "https://pub.dartlang.org"
3030
source: hosted
31-
version: "1.2.0"
31+
version: "1.2.1"
3232
charcode:
3333
dependency: transitive
3434
description:
@@ -42,21 +42,7 @@ packages:
4242
name: clock
4343
url: "https://pub.dartlang.org"
4444
source: hosted
45-
version: "1.1.0"
46-
cloud_firestore_platform_interface:
47-
dependency: transitive
48-
description:
49-
name: cloud_firestore_platform_interface
50-
url: "https://pub.dartlang.org"
51-
source: hosted
52-
version: "5.8.2"
53-
cloud_firestore_web:
54-
dependency: transitive
55-
description:
56-
name: cloud_firestore_web
57-
url: "https://pub.dartlang.org"
58-
source: hosted
59-
version: "3.0.2"
45+
version: "1.1.1"
6046
collection:
6147
dependency: transitive
6248
description:
@@ -77,56 +63,56 @@ packages:
7763
name: fake_async
7864
url: "https://pub.dartlang.org"
7965
source: hosted
80-
version: "1.3.0"
66+
version: "1.3.1"
8167
firebase_auth:
8268
dependency: transitive
8369
description:
8470
name: firebase_auth
8571
url: "https://pub.dartlang.org"
8672
source: hosted
87-
version: "4.0.2"
73+
version: "4.2.5"
8874
firebase_auth_platform_interface:
8975
dependency: transitive
9076
description:
9177
name: firebase_auth_platform_interface
9278
url: "https://pub.dartlang.org"
9379
source: hosted
94-
version: "6.10.4"
80+
version: "6.11.7"
9581
firebase_auth_web:
9682
dependency: transitive
9783
description:
9884
name: firebase_auth_web
9985
url: "https://pub.dartlang.org"
10086
source: hosted
101-
version: "5.0.2"
87+
version: "5.2.4"
10288
firebase_core:
10389
dependency: "direct main"
10490
description:
10591
name: firebase_core
10692
url: "https://pub.dartlang.org"
10793
source: hosted
108-
version: "2.1.0"
94+
version: "2.4.1"
10995
firebase_core_platform_interface:
11096
dependency: transitive
11197
description:
11298
name: firebase_core_platform_interface
11399
url: "https://pub.dartlang.org"
114100
source: hosted
115-
version: "4.5.1"
101+
version: "4.5.2"
116102
firebase_core_web:
117103
dependency: transitive
118104
description:
119105
name: firebase_core_web
120106
url: "https://pub.dartlang.org"
121107
source: hosted
122-
version: "2.0.0"
108+
version: "2.1.0"
123109
firebase_phone_auth_handler:
124110
dependency: "direct main"
125111
description:
126112
path: ".."
127113
relative: true
128114
source: path
129-
version: "1.0.7"
115+
version: "1.0.8"
130116
flutter:
131117
dependency: "direct main"
132118
description: flutter
@@ -190,21 +176,21 @@ packages:
190176
name: matcher
191177
url: "https://pub.dartlang.org"
192178
source: hosted
193-
version: "0.12.11"
179+
version: "0.12.12"
194180
material_color_utilities:
195181
dependency: transitive
196182
description:
197183
name: material_color_utilities
198184
url: "https://pub.dartlang.org"
199185
source: hosted
200-
version: "0.1.4"
186+
version: "0.1.5"
201187
meta:
202188
dependency: transitive
203189
description:
204190
name: meta
205191
url: "https://pub.dartlang.org"
206192
source: hosted
207-
version: "1.7.0"
193+
version: "1.8.0"
208194
nested:
209195
dependency: transitive
210196
description:
@@ -218,7 +204,7 @@ packages:
218204
name: path
219205
url: "https://pub.dartlang.org"
220206
source: hosted
221-
version: "1.8.1"
207+
version: "1.8.2"
222208
pinput:
223209
dependency: "direct main"
224210
description:
@@ -232,14 +218,14 @@ packages:
232218
name: plugin_platform_interface
233219
url: "https://pub.dartlang.org"
234220
source: hosted
235-
version: "2.1.2"
221+
version: "2.1.3"
236222
provider:
237223
dependency: transitive
238224
description:
239225
name: provider
240226
url: "https://pub.dartlang.org"
241227
source: hosted
242-
version: "6.0.4"
228+
version: "6.0.5"
243229
sky_engine:
244230
dependency: transitive
245231
description: flutter
@@ -258,7 +244,7 @@ packages:
258244
name: source_span
259245
url: "https://pub.dartlang.org"
260246
source: hosted
261-
version: "1.8.2"
247+
version: "1.9.0"
262248
stack_trace:
263249
dependency: transitive
264250
description:
@@ -279,21 +265,21 @@ packages:
279265
name: string_scanner
280266
url: "https://pub.dartlang.org"
281267
source: hosted
282-
version: "1.1.0"
268+
version: "1.1.1"
283269
term_glyph:
284270
dependency: transitive
285271
description:
286272
name: term_glyph
287273
url: "https://pub.dartlang.org"
288274
source: hosted
289-
version: "1.2.0"
275+
version: "1.2.1"
290276
test_api:
291277
dependency: transitive
292278
description:
293279
name: test_api
294280
url: "https://pub.dartlang.org"
295281
source: hosted
296-
version: "0.4.9"
282+
version: "0.4.12"
297283
typed_data:
298284
dependency: transitive
299285
description:

lib/src/auth_controller.dart

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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;

lib/src/auth_handler.dart

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class FirebasePhoneAuthHandler extends StatefulWidget {
1919
this.onError,
2020
this.onCodeSent,
2121
this.signOutOnSuccessfulVerification = false,
22+
this.sendOtpOnInitialize = true,
2223
this.linkWithExistingUser = false,
2324
this.autoRetrievalTimeOutDuration =
2425
FirebasePhoneAuthController.kAutoRetrievalTimeOutDuration,
@@ -58,6 +59,11 @@ class FirebasePhoneAuthHandler extends StatefulWidget {
5859
/// {@endtemplate}
5960
final VoidCallback? onCodeSent;
6061

62+
/// {@template sendOtpOnInitialize}
63+
/// Whether to send OTP as soon as the widget initializes or not
64+
/// {@endtemplate}
65+
final bool sendOtpOnInitialize;
66+
6167
/// {@template linkWithExistingUser}
6268
///
6369
/// If true, links the generated credentials to an existing signed in user,
@@ -198,17 +204,17 @@ class _FirebasePhoneAuthHandlerState extends State<FirebasePhoneAuthHandler> {
198204
recaptchaVerifierForWeb: captcha,
199205
);
200206

201-
await con.sendOTP();
207+
if (widget.sendOtpOnInitialize) await con.sendOTP();
202208
})();
203209
super.initState();
204210
}
205211

206212
@override
207-
void dispose() {
213+
void deactivate() {
208214
try {
209215
FirebasePhoneAuthController._of(context, listen: false).clear();
210216
} catch (_) {}
211-
super.dispose();
217+
super.deactivate();
212218
}
213219

214220
@override

0 commit comments

Comments
 (0)