Skip to content

Commit d262d3c

Browse files
authored
New APIs for PhoneAuthCredential and PhoneAuthProvider (#698)
- `PhoneAuthCredential.SmsCode` - `PhoneAuthProvider.VerificationCompleted(PhoneAuthCredential)` - `PhoneAuthProvider.GetCredential()` - `PhoneAuthProvider.VerifyPhoneNumber(PhoneAuthOptions, VerificationCompleted, VerificationFailed, CodeSent, CodeAutoRetrievalTimeOut)`
1 parent ebeb50d commit d262d3c

File tree

2 files changed

+151
-15
lines changed

2 files changed

+151
-15
lines changed

auth/src/PhoneAuthProvider.cs

Lines changed: 91 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ public sealed class PhoneAuthProvider : global::System.IDisposable {
7070
/// Callback used when phone number auto-verification succeeded.
7171
[System.Obsolete("Please use `VerificationCompleted(PhoneAuthCredential)` instead", false)]
7272
public delegate void VerificationCompleted_DEPRECATED(Credential credential);
73+
/// Callback used when phone number auto-verification succeeded.
74+
public delegate void VerificationCompleted(PhoneAuthCredential credential);
7375
/// Callback used when phone number verification fails.
7476
public delegate void VerificationFailed(string error);
7577
/// Callback used when a verification code is sent to the given number.
@@ -82,7 +84,8 @@ public delegate void CodeSent(string verificationId,
8284

8385
// Class to hold the delegates the user provides to the verification flow.
8486
private class PhoneAuthDelegates {
85-
public VerificationCompleted_DEPRECATED verificationCompleted;
87+
public VerificationCompleted_DEPRECATED verificationCompleted_DEPRECATED;
88+
public VerificationCompleted verificationCompleted;
8689
public VerificationFailed verificationFailed;
8790
public CodeSent codeSent;
8891
public CodeAutoRetrievalTimeOut timeOut;
@@ -99,12 +102,14 @@ private class PhoneAuthDelegates {
99102
/// when the C++ library indicates a callback.
100103
///
101104
/// @return The unique identifier for the cached callbacks.
102-
private static int SaveCallbacks(VerificationCompleted_DEPRECATED verificationCompleted,
105+
private static int SaveCallbacks(VerificationCompleted_DEPRECATED verificationCompleted_DEPRECATED,
106+
VerificationCompleted verificationCompleted,
103107
VerificationFailed verificationFailed,
104108
CodeSent codeSent,
105109
CodeAutoRetrievalTimeOut timeOut) {
106110
int uid = uidGenerator++;
107111
var delegates = new PhoneAuthDelegates {
112+
verificationCompleted_DEPRECATED = verificationCompleted_DEPRECATED,
108113
verificationCompleted = verificationCompleted,
109114
verificationFailed = verificationFailed,
110115
codeSent = codeSent,
@@ -117,10 +122,27 @@ private static int SaveCallbacks(VerificationCompleted_DEPRECATED verificationCo
117122
}
118123

119124
[MonoPInvokeCallback(typeof(PhoneAuthProviderInternal.VerificationCompletedDelegate_DEPRECATED))]
120-
private static void VerificationCompleted_DEPRECATEDHandler(int callbackId,
125+
private static void VerificationCompletedHandler_DEPRECATED(int callbackId,
121126
System.IntPtr credential) {
122127
ExceptionAggregator.Wrap(() => {
123128
Credential c = new Credential(credential, true);
129+
lock (authCallbacks) {
130+
PhoneAuthDelegates callbacks;
131+
if (authCallbacks.TryGetValue(callbackId, out callbacks) &&
132+
callbacks.verificationCompleted_DEPRECATED != null) {
133+
callbacks.verificationCompleted_DEPRECATED(c);
134+
} else {
135+
c.Dispose();
136+
}
137+
}
138+
});
139+
}
140+
141+
[MonoPInvokeCallback(typeof(PhoneAuthProviderInternal.VerificationCompletedDelegate))]
142+
private static void VerificationCompletedHandler(int callbackId,
143+
System.IntPtr credential) {
144+
ExceptionAggregator.Wrap(() => {
145+
PhoneAuthCredential c = new PhoneAuthCredential(credential, true);
124146
lock (authCallbacks) {
125147
PhoneAuthDelegates callbacks;
126148
if (authCallbacks.TryGetValue(callbackId, out callbacks) &&
@@ -178,7 +200,11 @@ private static void TimeOutHandler(int callbackId, string verificationId) {
178200
private static PhoneAuthProviderInternal.VerificationCompletedDelegate_DEPRECATED
179201
verificationCompletedDelegate_DEPRECATED =
180202
new PhoneAuthProviderInternal.VerificationCompletedDelegate_DEPRECATED(
181-
VerificationCompleted_DEPRECATEDHandler);
203+
VerificationCompletedHandler_DEPRECATED);
204+
private static PhoneAuthProviderInternal.VerificationCompletedDelegate
205+
verificationCompletedDelegate =
206+
new PhoneAuthProviderInternal.VerificationCompletedDelegate(
207+
VerificationCompletedHandler);
182208
private static PhoneAuthProviderInternal.VerificationFailedDelegate
183209
verificationFailedDelegate =
184210
new PhoneAuthProviderInternal.VerificationFailedDelegate(
@@ -197,6 +223,7 @@ private static void InitializeCallbacks() {
197223
if (!callbacksInitialized) {
198224
callbacksInitialized = true;
199225
PhoneAuthProviderInternal.SetCallbacks(verificationCompletedDelegate_DEPRECATED,
226+
verificationCompletedDelegate,
200227
verificationFailedDelegate,
201228
codeSentDelegate,
202229
timeOutDelegate);
@@ -369,15 +396,59 @@ public void VerifyPhoneNumber(string phoneNumber, uint autoVerifyTimeOutMs,
369396
VerificationFailed verificationFailed,
370397
CodeSent codeSent,
371398
CodeAutoRetrievalTimeOut codeAutoRetrievalTimeOut) {
372-
int callbackId = SaveCallbacks(verificationCompleted, verificationFailed,
373-
codeSent, codeAutoRetrievalTimeOut);
399+
int callbackId = SaveCallbacks(
400+
verificationCompleted_DEPRECATED: verificationCompleted,
401+
verificationCompleted: null,
402+
verificationFailed: verificationFailed,
403+
codeSent: codeSent,
404+
timeOut: codeAutoRetrievalTimeOut);
374405
System.IntPtr listener = InternalProvider.VerifyPhoneNumberInternal(
375406
phoneNumber, autoVerifyTimeOutMs, forceResendingToken, callbackId);
376407
lock (cppListeners) {
377408
cppListeners.Add(callbackId, listener);
378409
}
379410
}
380411

412+
413+
/// Start the phone number authentication operation.
414+
///
415+
/// @note On iOS the verificationCompleted callback is never invoked and the
416+
/// codeAutoRetrievalTimeOut callback is invoked immediately since auto-validation is not
417+
/// supported on that platform.
418+
///
419+
/// @param[in] options The PhoneAuthOptions struct with a verification
420+
/// configuration.
421+
/// @param[in] verificationCompleted Phone number auto-verification succeeded.
422+
/// Called when auto-sms-retrieval or instant validation succeeds.
423+
/// Provided with the completed credential.
424+
/// @param[in] verificationFailed Phone number verification failed with an
425+
/// error. For example, quota exceeded or unknown phone number format.
426+
/// Provided with a description of the error.
427+
/// @param[in] codeSent SMS message with verification code sent to phone
428+
/// number. Provided with the verification id to pass along to
429+
/// `GetCredential` along with the sent code, and a token to use if
430+
/// the user requests another SMS message be sent.
431+
/// @param[in] codeAutoRetrievalTimeOut The timeout specified has expired.
432+
/// Provided with the verification id for the transaction that timed out.
433+
public void VerifyPhoneNumber(
434+
PhoneAuthOptions options,
435+
VerificationCompleted verificationCompleted,
436+
VerificationFailed verificationFailed,
437+
CodeSent codeSent,
438+
CodeAutoRetrievalTimeOut codeAutoRetrievalTimeOut) {
439+
int callbackId = SaveCallbacks(
440+
verificationCompleted_DEPRECATED: null,
441+
verificationCompleted: verificationCompleted,
442+
verificationFailed: verificationFailed,
443+
codeSent: codeSent,
444+
timeOut: codeAutoRetrievalTimeOut);
445+
System.IntPtr listener = InternalProvider.VerifyPhoneNumberInternal(
446+
options, callbackId);
447+
lock (cppListeners) {
448+
cppListeners.Add(callbackId, listener);
449+
}
450+
}
451+
381452
// The SWIG generated PhoneAuthProvider which contains the C++ object.
382453
private PhoneAuthProviderInternal InternalProvider;
383454
internal PhoneAuthProvider(FirebaseAuth auth) {
@@ -435,6 +506,20 @@ public Credential GetCredential_DEPRECATED(string verificationId,
435506
string verificationCode) {
436507
return InternalProvider.GetCredential_DEPRECATED(verificationId, verificationCode);
437508
}
509+
510+
/// Generate a credential for the given phone number.
511+
///
512+
/// @param[in] verification_id The id returned when sending the verification
513+
/// code. Sent to the caller via @ref Listener::OnCodeSent.
514+
/// @param[in] verification_code The verification code supplied by the user,
515+
/// most likely by a GUI where the user manually enters the code
516+
/// received in the SMS sent by @ref VerifyPhoneNumber.
517+
///
518+
/// @returns New PhoneAuthCredential.
519+
public PhoneAuthCredential GetCredential(string verificationId,
520+
string verificationCode) {
521+
return InternalProvider.GetCredential(verificationId, verificationCode);
522+
}
438523
}
439524

440525
} // namespace Firebase.Auth

auth/src/swig/auth.i

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,22 @@ static CppInstanceManager<Auth> g_auth_instances;
10201020
%typemap(csclassmodifiers) firebase::auth::Credential "public class";
10211021
%typemap(csclassmodifiers) firebase::auth::PhoneAuthCredential "public sealed class";
10221022

1023+
%attributestring(firebase::auth::PhoneAuthCredential, std::string, SmsCodeInternal, sms_code);
1024+
%typemap(cscode) firebase::auth::PhoneAuthCredential %{
1025+
/// Gets the auto-retrieved SMS verification code if applicable.
1026+
///
1027+
/// This method is supported on Android devices only. It will return empty strings on
1028+
/// other platforms.
1029+
///
1030+
/// When SMS verification is used, you will be called back first via
1031+
/// @ref PhoneAuthProvider.CodeSent, and later
1032+
/// PhoneAuthProvider.VerificationCompleted with a PhoneAuthCredential containing
1033+
/// a non-null SMS code if auto-retrieval succeeded. If Firebase used another approach
1034+
/// to verify the phone number and triggers a callback via
1035+
/// @ref PhoneAuthProvider.VerificationCompleted, then the SMS code can be null.
1036+
public string SmsCode { get { return SmsCodeInternal; } }
1037+
%}
1038+
10231039
%typemap(csclassmodifiers) firebase::auth::FederatedAuthProvider "public class";
10241040

10251041
%typemap(csclassmodifiers) firebase::auth::FederatedOAuthProvider
@@ -1514,6 +1530,8 @@ namespace auth {
15141530

15151531
// The callbacks that are used by the Phone Auth Listener, that need to reach
15161532
// back to C# callbacks.
1533+
typedef void (SWIGSTDCALL *VerificationCompletedCallback_DEPRECATED)(
1534+
int callback_id, void* credential);
15171535
typedef void (SWIGSTDCALL *VerificationCompletedCallback)(
15181536
int callback_id, void* credential);
15191537
typedef void (SWIGSTDCALL *VerificationFailedCallback)(
@@ -1537,10 +1555,10 @@ class PhoneAuthListenerImpl
15371555
// OnVerificationCompleted(PhoneAuthCredential) will be triggered. We
15381556
// support both delegates but the user needs to choose to use only one of
15391557
// them.
1540-
if (g_verification_completed_callback) {
1558+
if (g_verification_completed_callback_DEPRECATED) {
15411559
firebase::callback::AddCallback(
15421560
new firebase::callback::CallbackValue2<int, Credential>(
1543-
callback_id_, credential, VerificationCompleted));
1561+
callback_id_, credential, VerificationCompleted_DEPRECATED));
15441562
}
15451563
}
15461564

@@ -1549,8 +1567,11 @@ class PhoneAuthListenerImpl
15491567
// OnVerificationCompleted(PhoneAuthCredential) will be triggered. We
15501568
// support both delegates but the user needs to choose to use only one of
15511569
// them.
1552-
1553-
// TODO(IO2023): Add hooks to new PhoneAuthCredential. Need new delegates.
1570+
if (g_verification_completed_callback) {
1571+
firebase::callback::AddCallback(
1572+
new firebase::callback::CallbackValue2<int, PhoneAuthCredential>(
1573+
callback_id_, credential, VerificationCompleted));
1574+
}
15541575
}
15551576

15561577
virtual void OnVerificationFailed(const std::string& error) {
@@ -1584,11 +1605,13 @@ class PhoneAuthListenerImpl
15841605
}
15851606

15861607
// Called from C# to pass along the C# functions to be called.
1587-
static void SetCallbacks(VerificationCompletedCallback completed_callback,
1608+
static void SetCallbacks(VerificationCompletedCallback_DEPRECATED completed_callback_DEPRECATED,
1609+
VerificationCompletedCallback completed_callback,
15881610
VerificationFailedCallback failed_callback,
15891611
CodeSentCallback sent_callback,
15901612
TimeOutCallback time_callback) {
15911613
MutexLock lock(g_mutex);
1614+
g_verification_completed_callback_DEPRECATED = completed_callback_DEPRECATED;
15921615
g_verification_completed_callback = completed_callback;
15931616
g_verification_failed_callback = failed_callback;
15941617
g_code_sent_callback = sent_callback;
@@ -1598,16 +1621,26 @@ class PhoneAuthListenerImpl
15981621
int callback_id_;
15991622

16001623
static Mutex g_mutex;
1624+
static VerificationCompletedCallback_DEPRECATED g_verification_completed_callback_DEPRECATED;
16011625
static VerificationCompletedCallback g_verification_completed_callback;
16021626
static VerificationFailedCallback g_verification_failed_callback;
16031627
static CodeSentCallback g_code_sent_callback;
16041628
static TimeOutCallback g_time_out_callback;
16051629

1606-
static void VerificationCompleted(int callback_id, Credential credential) {
1630+
static void VerificationCompleted_DEPRECATED(int callback_id, Credential credential) {
16071631
MutexLock lock(g_mutex);
1608-
if (g_verification_completed_callback) {
1632+
if (g_verification_completed_callback_DEPRECATED) {
16091633
// Copy the credential so it can be owned by the C# proxy object.
16101634
Credential* copy = new Credential(credential);
1635+
g_verification_completed_callback_DEPRECATED(callback_id, copy);
1636+
}
1637+
}
1638+
1639+
static void VerificationCompleted(int callback_id, PhoneAuthCredential credential) {
1640+
MutexLock lock(g_mutex);
1641+
if (g_verification_completed_callback) {
1642+
// Copy the credential so it can be owned by the C# proxy object.
1643+
PhoneAuthCredential* copy = new PhoneAuthCredential(credential);
16111644
g_verification_completed_callback(callback_id, copy);
16121645
}
16131646
}
@@ -1643,6 +1676,7 @@ class PhoneAuthListenerImpl
16431676
};
16441677

16451678
Mutex PhoneAuthListenerImpl::g_mutex;
1679+
VerificationCompletedCallback_DEPRECATED PhoneAuthListenerImpl::g_verification_completed_callback_DEPRECATED = nullptr;
16461680
VerificationCompletedCallback PhoneAuthListenerImpl::g_verification_completed_callback = nullptr;
16471681
VerificationFailedCallback PhoneAuthListenerImpl::g_verification_failed_callback = nullptr;
16481682
CodeSentCallback PhoneAuthListenerImpl::g_code_sent_callback = nullptr;
@@ -1666,6 +1700,17 @@ TimeOutCallback PhoneAuthListenerImpl::g_time_out_callback = nullptr;
16661700
return listener;
16671701
}
16681702

1703+
// Creates a new Listener with the given callback_id to handle the call.
1704+
// Returns that Listener, so the caller can manage that memory.
1705+
void* VerifyPhoneNumberInternal(
1706+
const PhoneAuthOptions& options,
1707+
int callback_id) {
1708+
firebase::auth::PhoneAuthListenerImpl* listener =
1709+
new firebase::auth::PhoneAuthListenerImpl(callback_id);
1710+
self->VerifyPhoneNumber(options, listener);
1711+
return listener;
1712+
}
1713+
16691714
// Destroys the provided Listener implementation.
16701715
void DestroyListenerImplInternal(void* listener) {
16711716
assert(listener);
@@ -1674,26 +1719,32 @@ TimeOutCallback PhoneAuthListenerImpl::g_time_out_callback = nullptr;
16741719

16751720
// Save the C# callbacks so they can be called later.
16761721
static void SetCallbacks(
1722+
firebase::auth::VerificationCompletedCallback_DEPRECATED completed_callback_DEPRECATED,
16771723
firebase::auth::VerificationCompletedCallback completed_callback,
16781724
firebase::auth::VerificationFailedCallback failed_callback,
16791725
firebase::auth::CodeSentCallback sent_callback,
16801726
firebase::auth::TimeOutCallback time_out_callback) {
16811727
firebase::auth::PhoneAuthListenerImpl::SetCallbacks(
1682-
completed_callback, failed_callback, sent_callback, time_out_callback);
1728+
completed_callback_DEPRECATED, completed_callback, failed_callback,
1729+
sent_callback, time_out_callback);
16831730
}
16841731
}
16851732

16861733
%typemap(cscode) firebase::auth::PhoneAuthProvider %{
16871734
public delegate void VerificationCompletedDelegate_DEPRECATED(int callbackId, System.IntPtr credential);
1735+
public delegate void VerificationCompletedDelegate(int callbackId, System.IntPtr credential);
16881736
public delegate void VerificationFailedDelegate(int callbackId, string error);
16891737
public delegate void CodeSentDelegate(int callbackId, string verificationId, System.IntPtr token);
16901738
public delegate void TimeOutDelegate(int callbackId, string verificationId);
16911739
%}
16921740

16931741
// Map callback function types delegates.
16941742
SWIG_MAP_CFUNC_TO_CSDELEGATE(
1695-
::firebase::auth::VerificationCompletedCallback,
1743+
::firebase::auth::VerificationCompletedCallback_DEPRECATED,
16961744
Firebase.Auth.PhoneAuthProviderInternal.VerificationCompletedDelegate_DEPRECATED)
1745+
SWIG_MAP_CFUNC_TO_CSDELEGATE(
1746+
::firebase::auth::VerificationCompletedCallback,
1747+
Firebase.Auth.PhoneAuthProviderInternal.VerificationCompletedDelegate)
16971748
SWIG_MAP_CFUNC_TO_CSDELEGATE(
16981749
::firebase::auth::VerificationFailedCallback,
16991750
Firebase.Auth.PhoneAuthProviderInternal.VerificationFailedDelegate)

0 commit comments

Comments
 (0)