Skip to content

Commit

Permalink
feat(authentication): provide the auto-retrieved SMS verification code (
Browse files Browse the repository at this point in the history
  • Loading branch information
robingenz authored Dec 4, 2022
1 parent e0830a0 commit 4c00b61
Show file tree
Hide file tree
Showing 10 changed files with 262 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/spotty-tigers-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@capacitor-firebase/authentication": minor
---

feat(android): provide the auto-retrieved SMS verification code
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

96 changes: 91 additions & 5 deletions packages/authentication/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,9 @@ const useEmulator = async () => {
* [`useAppLanguage()`](#useapplanguage)
* [`useEmulator(...)`](#useemulator)
* [`addListener('authStateChange', ...)`](#addlistenerauthstatechange)
* [`addListener('phoneVerificationCompleted', ...)`](#addlistenerphoneverificationcompleted)
* [`addListener('phoneVerificationFailed', ...)`](#addlistenerphoneverificationfailed)
* [`addListener('phoneCodeSent', ...)`](#addlistenerphonecodesent)
* [`removeAllListeners()`](#removealllisteners)
* [Interfaces](#interfaces)
* [Type Aliases](#type-aliases)
Expand Down Expand Up @@ -1293,6 +1296,68 @@ Listen for the user's sign-in state changes.
--------------------


### addListener('phoneVerificationCompleted', ...)

```typescript
addListener(eventName: 'phoneVerificationCompleted', listenerFunc: PhoneVerificationCompletedListener) => Promise<PluginListenerHandle> & PluginListenerHandle
```

Listen for a completed phone verification.

Only available for Android.

| Param | Type |
| ------------------ | ------------------------------------------------------------------------------------------------- |
| **`eventName`** | <code>'phoneVerificationCompleted'</code> |
| **`listenerFunc`** | <code><a href="#phoneverificationcompletedlistener">PhoneVerificationCompletedListener</a></code> |

**Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt; & <a href="#pluginlistenerhandle">PluginListenerHandle</a></code>

**Since:** 1.3.0

--------------------


### addListener('phoneVerificationFailed', ...)

```typescript
addListener(eventName: 'phoneVerificationFailed', listenerFunc: PhoneVerificationFailedListener) => Promise<PluginListenerHandle> & PluginListenerHandle
```

Listen for a failed phone verification.

| Param | Type |
| ------------------ | ------------------------------------------------------------------------------------------- |
| **`eventName`** | <code>'phoneVerificationFailed'</code> |
| **`listenerFunc`** | <code><a href="#phoneverificationfailedlistener">PhoneVerificationFailedListener</a></code> |

**Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt; & <a href="#pluginlistenerhandle">PluginListenerHandle</a></code>

**Since:** 1.3.0

--------------------


### addListener('phoneCodeSent', ...)

```typescript
addListener(eventName: 'phoneCodeSent', listenerFunc: PhoneCodeSentListener) => Promise<PluginListenerHandle> & PluginListenerHandle
```

Listen for a phone verification code.

| Param | Type |
| ------------------ | ----------------------------------------------------------------------- |
| **`eventName`** | <code>'phoneCodeSent'</code> |
| **`listenerFunc`** | <code><a href="#phonecodesentlistener">PhoneCodeSentListener</a></code> |

**Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt; & <a href="#pluginlistenerhandle">PluginListenerHandle</a></code>

**Since:** 1.3.0

--------------------


### removeAllListeners()

```typescript
Expand Down Expand Up @@ -1544,11 +1609,11 @@ bundle identifiers.

#### SignInWithPhoneNumberOptions

| Prop | Type | Description | Since |
| ---------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **`phoneNumber`** | <code>string</code> | The phone number to be verified. | 0.1.0 |
| **`verificationId`** | <code>string</code> | The verification ID which will be returned when `signInWithPhoneNumber` is called for the first time. The `verificationCode` must also be provided. | 0.1.0 |
| **`verificationCode`** | <code>string</code> | The verification code from the SMS message. The `verificationId` must also be provided. | 0.1.0 |
| Prop | Type | Description | Since |
| ---------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **`phoneNumber`** | <code>string</code> | The phone number to be verified. Cannot be used in combination with `verificationId` and `verificationCode`. Use the `phoneVerificationCompleted` listener to be notified when the verification is completed. Use the `phoneVerificationFailed` listener to be notified when the verification is failed. Use the `phoneCodeSent` listener to get the verification id. | 0.1.0 |
| **`verificationId`** | <code>string</code> | The verification ID received from the `phoneCodeSent` listener. The `verificationCode` must also be provided. | 0.1.0 |
| **`verificationCode`** | <code>string</code> | The verification code either received from the `phoneCodeSent` listener or entered by the user. The `verificationId` must also be provided. | 0.1.0 |


#### UnlinkResult
Expand Down Expand Up @@ -1621,6 +1686,27 @@ Callback to receive the user's sign-in state change notifications.
<code>(change: <a href="#authstatechange">AuthStateChange</a>): void</code>


#### PhoneVerificationCompletedListener

Callback to receive the verification code sent to the user's phone number.

<code>(event: { verificationCode: string; }): void</code>


#### PhoneVerificationFailedListener

Callback to receive notifications of failed phone verification.

<code>(event: { message: string; }): void</code>


#### PhoneCodeSentListener

Callback to receive the verification ID.

<code>(event: { verificationId: string; }): void</code>


### Enums


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,18 @@ public void handleFailedLink(final PluginCall call, String message, Exception ex
call.reject(message, exception);
}

public void handlePhoneVerificationCompleted(String smsCode) {
plugin.handlePhoneVerificationCompleted(smsCode);
}

public void handlePhoneVerificationFailed(Exception exception) {
plugin.handlePhoneVerificationFailed(exception);
}

public void handlePhoneCodeSent(String verificationId) {
plugin.handlePhoneCodeSent(verificationId);
}

public FirebaseAuth getFirebaseAuthInstance() {
return firebaseAuthInstance;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.ActivityCallback;
import com.getcapacitor.annotation.CapacitorPlugin;
import com.google.firebase.FirebaseException;
import com.google.firebase.auth.ActionCodeSettings;
import com.google.firebase.auth.FirebaseUser;
import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.FacebookAuthProviderHandler;
Expand All @@ -16,6 +17,9 @@
public class FirebaseAuthenticationPlugin extends Plugin {

public static final String TAG = "FirebaseAuthentication";
public static final String PHONE_VERIFICATION_COMPLETED_EVENT = "phoneVerificationCompleted";
public static final String PHONE_VERIFICATION_FAILED_EVENT = "phoneVerificationFailed";
public static final String PHONE_CODE_SENT_EVENT = "phoneCodeSent";
public static final String ERROR_PROVIDER_ID_MISSING = "providerId must be provided.";
public static final String ERROR_NO_USER_SIGNED_IN = "No user is signed in.";
public static final String ERROR_OOB_CODE_MISSING = "oobCode must be provided.";
Expand Down Expand Up @@ -591,6 +595,24 @@ public void useEmulator(PluginCall call) {
}
}

public void handlePhoneVerificationCompleted(String smsCode) {
JSObject result = new JSObject();
result.put("verificationCode", smsCode);
notifyListeners(PHONE_VERIFICATION_COMPLETED_EVENT, result, true);
}

public void handlePhoneVerificationFailed(Exception exception) {
JSObject result = new JSObject();
result.put("message", exception.getLocalizedMessage());
notifyListeners(PHONE_VERIFICATION_FAILED_EVENT, result, true);
}

public void handlePhoneCodeSent(String verificationId) {
JSObject result = new JSObject();
result.put("verificationId", verificationId);
notifyListeners(PHONE_CODE_SENT_EVENT, result, true);
}

@Override
public void startActivityForResult(PluginCall call, Intent intent, String callbackName) {
super.startActivityForResult(call, intent, callbackName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ private PhoneAuthProvider.OnVerificationStateChangedCallbacks createCallbacks(fi
return new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onVerificationCompleted(PhoneAuthCredential credential) {
String smsCode = credential.getSmsCode();
pluginImplementation.handlePhoneVerificationCompleted(smsCode);
/**
* @deprecated This code was replaced by event listener.
*
* Caution: The call must be resolved earlier.
*/
if (isLink) {
pluginImplementation.handleSuccessfulLink(call, credential, null, null, null);
} else {
Expand All @@ -76,6 +83,12 @@ public void onVerificationCompleted(PhoneAuthCredential credential) {

@Override
public void onVerificationFailed(FirebaseException exception) {
pluginImplementation.handlePhoneVerificationFailed(exception);
/**
* @deprecated This code was replaced by event listener.
*
* Caution: The call must be resolved earlier.
*/
if (isLink) {
pluginImplementation.handleFailedLink(call, null, exception);
} else {
Expand All @@ -85,6 +98,12 @@ public void onVerificationFailed(FirebaseException exception) {

@Override
public void onCodeSent(@NonNull String verificationId, @NonNull PhoneAuthProvider.ForceResendingToken token) {
pluginImplementation.handlePhoneCodeSent(verificationId);
/**
* @deprecated This code was replaced by event listener.
*
* Caution: The call must be resolved earlier.
*/
JSObject result = FirebaseAuthenticationHelper.createSignInResult(null, null, null, null, null, null);
result.put("verificationId", verificationId);
call.resolve(result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,14 @@ public typealias AuthStateChangedObserver = () -> Void
savedCall.reject(errorMessage, nil, error)
}

func handlePhoneVerificationFailed(_ error: Error) {
plugin.handlePhoneVerificationFailed(error)
}

func handlePhoneCodeSent(_ verificationId: String) {
plugin.handlePhoneCodeSent(verificationId)
}

func getPlugin() -> FirebaseAuthenticationPlugin {
return self.plugin
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class FirebaseAuthenticationPlugin: CAPPlugin {
"signInAnonymously cannot be used in combination with skipNativeAuth."
public let errorDeviceUnsupported = "Device is not supported. At least iOS 13 is required."
public let authStateChangeEvent = "authStateChange"
public let phoneVerificationFailedEvent = "phoneVerificationFailed"
public let phoneCodeSentEvent = "phoneCodeSent"
private var implementation: FirebaseAuthentication?

override public func load() {
Expand Down Expand Up @@ -429,6 +431,18 @@ public class FirebaseAuthenticationPlugin: CAPPlugin {
notifyListeners(authStateChangeEvent, data: result, retainUntilConsumed: true)
}

@objc func handlePhoneVerificationFailed(_ error: Error) {
var result = JSObject()
result["message"] = error.localizedDescription
notifyListeners(phoneVerificationFailedEvent, data: result, retainUntilConsumed: true)
}

@objc func handlePhoneCodeSent(_ verificationId: String) {
var result = JSObject()
result["verificationId"] = verificationId
notifyListeners(phoneCodeSentEvent, data: result, retainUntilConsumed: true)
}

private func firebaseAuthenticationConfig() -> FirebaseAuthenticationConfig {
var config = FirebaseAuthenticationConfig()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ class PhoneAuthProviderHandler: NSObject {
}
PhoneAuthProvider.provider()
.verifyPhoneNumber(phoneNumber, uiDelegate: nil) { verificationID, error in
/**
* @deprecated This code was replaced by event listener.
*
* Caution: The call must be resolved earlier.
*/
if let error = error {
self.pluginImplementation.handlePhoneVerificationFailed(error)
if isLink == true {
self.pluginImplementation.handleFailedLink(message: nil, error: error)
} else {
Expand All @@ -50,6 +56,7 @@ class PhoneAuthProviderHandler: NSObject {
return
}

self.pluginImplementation.handlePhoneCodeSent(verificationID ?? "")
var result = FirebaseAuthenticationHelper.createSignInResult(credential: nil, user: nil, idToken: nil, nonce: nil, accessToken: nil, additionalUserInfo: nil)
result["verificationId"] = verificationID
call.resolve(result)
Expand Down
Loading

0 comments on commit 4c00b61

Please sign in to comment.