diff --git a/.changeset/selfish-windows-leave.md b/.changeset/selfish-windows-leave.md new file mode 100644 index 00000000..22c74755 --- /dev/null +++ b/.changeset/selfish-windows-leave.md @@ -0,0 +1,5 @@ +--- +"@capacitor-firebase/authentication": minor +--- + +feat: overwrite `skipNativeAuth` configuration option diff --git a/packages/authentication/README.md b/packages/authentication/README.md index 1152c463..1e8ebc2b 100644 --- a/packages/authentication/README.md +++ b/packages/authentication/README.md @@ -98,6 +98,23 @@ export default config; +## FAQ + +1. **What does this plugin do?** + This plugin enables the use of [Firebase Authentication](https://firebase.google.com/docs/auth) in a Capacitor app. + It uses the Firebase SDK for [Java](https://firebase.google.com/docs/reference/android) (Android), [Swift](https://firebase.google.com/docs/reference/swift) (iOS) and [JavaScript](https://firebase.google.com/docs/reference/js). +1. **What is the difference between the web implementation of this plugin and the Firebase JS SDK?** + The web implementation of this plugin encapsulates the Firebase JS SDK and enables a consistent interface across all platforms. + You can decide if you prefer to use the web implementation or the Firebase JS SDK. +1. **What is the difference between the native and web authentication?** + For web authentication, the Firebase JS SDK is used. This only works to a limited extent on Android and iOS in the WebViews (see [here](https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html)). + For native authentication, the native SDKs from Firebase, Google, etc. are used. + These offer all the functionalities that the Firebase JS SDK also offers on the web. + However, after a login with the native SDK, the user is only logged in on the native layer of the app. + If the user should also be logged in on the web layer, additional steps are required (see [here](/packages/authentication/docs/firebase-js-sdk.md)). +1. **How can I use this plugin with the Firebase JavaScript SDK?** + See [here](/packages/authentication/docs/firebase-js-sdk.md). + ## Demo A working example can be found here: [robingenz/capacitor-firebase-authentication-demo](https://github.com/robingenz/capacitor-firebase-authentication-demo) @@ -575,14 +592,14 @@ Sets the tenant id. ### signInWithApple(...) ```typescript -signInWithApple(options?: SignInOptions | undefined) => Promise +signInWithApple(options?: SignInOptions | SignInWithOAuthOptions | undefined) => Promise ``` Starts the Apple sign-in flow. -| Param | Type | -| ------------- | ------------------------------------------------------- | -| **`options`** | SignInOptions | +| Param | Type | +| ------------- | ----------------------------------------------------------------------------------------------------------------------- | +| **`options`** | SignInOptions \| SignInWithOAuthOptions | **Returns:** Promise<SignInResult> @@ -654,14 +671,14 @@ Signs in using an email and sign-in email link. ### signInWithFacebook(...) ```typescript -signInWithFacebook(options?: SignInOptions | undefined) => Promise +signInWithFacebook(options?: SignInOptions | SignInWithOAuthOptions | undefined) => Promise ``` Starts the Facebook sign-in flow. -| Param | Type | -| ------------- | ------------------------------------------------------- | -| **`options`** | SignInOptions | +| Param | Type | +| ------------- | ----------------------------------------------------------------------------------------------------------------------- | +| **`options`** | SignInOptions \| SignInWithOAuthOptions | **Returns:** Promise<SignInResult> @@ -673,14 +690,14 @@ Starts the Facebook sign-in flow. ### signInWithGithub(...) ```typescript -signInWithGithub(options?: SignInOptions | undefined) => Promise +signInWithGithub(options?: SignInOptions | SignInWithOAuthOptions | undefined) => Promise ``` Starts the GitHub sign-in flow. -| Param | Type | -| ------------- | ------------------------------------------------------- | -| **`options`** | SignInOptions | +| Param | Type | +| ------------- | ----------------------------------------------------------------------------------------------------------------------- | +| **`options`** | SignInOptions \| SignInWithOAuthOptions | **Returns:** Promise<SignInResult> @@ -692,14 +709,14 @@ Starts the GitHub sign-in flow. ### signInWithGoogle(...) ```typescript -signInWithGoogle(options?: SignInOptions | undefined) => Promise +signInWithGoogle(options?: SignInOptions | SignInWithOAuthOptions | undefined) => Promise ``` Starts the Google sign-in flow. -| Param | Type | -| ------------- | ------------------------------------------------------- | -| **`options`** | SignInOptions | +| Param | Type | +| ------------- | ----------------------------------------------------------------------------------------------------------------------- | +| **`options`** | SignInOptions \| SignInWithOAuthOptions | **Returns:** Promise<SignInResult> @@ -711,14 +728,14 @@ Starts the Google sign-in flow. ### signInWithMicrosoft(...) ```typescript -signInWithMicrosoft(options?: SignInOptions | undefined) => Promise +signInWithMicrosoft(options?: SignInOptions | SignInWithOAuthOptions | undefined) => Promise ``` Starts the Microsoft sign-in flow. -| Param | Type | -| ------------- | ------------------------------------------------------- | -| **`options`** | SignInOptions | +| Param | Type | +| ------------- | ----------------------------------------------------------------------------------------------------------------------- | +| **`options`** | SignInOptions \| SignInWithOAuthOptions | **Returns:** Promise<SignInResult> @@ -753,14 +770,14 @@ Only available for Android and iOS. ### signInWithPlayGames(...) ```typescript -signInWithPlayGames(options?: SignInOptions | undefined) => Promise +signInWithPlayGames(options?: SignInOptions | SignInWithOAuthOptions | undefined) => Promise ``` Starts the Play Games sign-in flow. -| Param | Type | -| ------------- | ------------------------------------------------------- | -| **`options`** | SignInOptions | +| Param | Type | +| ------------- | ----------------------------------------------------------------------------------------------------------------------- | +| **`options`** | SignInOptions \| SignInWithOAuthOptions | **Returns:** Promise<SignInResult> @@ -772,14 +789,14 @@ Starts the Play Games sign-in flow. ### signInWithTwitter(...) ```typescript -signInWithTwitter(options?: SignInOptions | undefined) => Promise +signInWithTwitter(options?: SignInOptions | SignInWithOAuthOptions | undefined) => Promise ``` Starts the Twitter sign-in flow. -| Param | Type | -| ------------- | ------------------------------------------------------- | -| **`options`** | SignInOptions | +| Param | Type | +| ------------- | ----------------------------------------------------------------------------------------------------------------------- | +| **`options`** | SignInOptions \| SignInWithOAuthOptions | **Returns:** Promise<SignInResult> @@ -791,14 +808,14 @@ Starts the Twitter sign-in flow. ### signInWithYahoo(...) ```typescript -signInWithYahoo(options?: SignInOptions | undefined) => Promise +signInWithYahoo(options?: SignInOptions | SignInWithOAuthOptions | undefined) => Promise ``` Starts the Yahoo sign-in flow. -| Param | Type | -| ------------- | ------------------------------------------------------- | -| **`options`** | SignInOptions | +| Param | Type | +| ------------- | ----------------------------------------------------------------------------------------------------------------------- | +| **`options`** | SignInOptions \| SignInWithOAuthOptions | **Returns:** Promise<SignInResult> @@ -1075,10 +1092,11 @@ bundle identifiers. #### SignInOptions -| Prop | Type | Description | Since | -| ---------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------- | ----- | -| **`customParameters`** | SignInCustomParameter[] | Configures custom parameters to be passed to the identity provider during the OAuth sign-in flow. | 0.1.0 | -| **`scopes`** | string[] | Scopes to request from provider. | 0.3.1 | +| Prop | Type | Description | Since | +| ---------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----- | +| **`customParameters`** | SignInCustomParameter[] | Configures custom parameters to be passed to the identity provider during the OAuth sign-in flow. | 0.1.0 | +| **`scopes`** | string[] | Scopes to request from provider. | 0.3.1 | +| **`skipNativeAuth`** | boolean | Whether the plugin should skip the native authentication or not. Only needed if you want to use the Firebase JavaScript SDK. This value overwrites the configrations value of the `skipNativeAuth` option. If no value is set, the configuration value is used. **Note that the plugin may behave differently across the platforms.** `skipNativeAuth` cannot be used in combination with `signInWithCustomToken`, `createUserWithEmailAndPassword` or `signInWithEmailAndPassword`. Only available for Android and iOS. | 1.1.0 | #### SignInCustomParameter @@ -1089,6 +1107,14 @@ bundle identifiers. | **`value`** | string | The custom parameter value (e.g. `user@firstadd.onmicrosoft.com`). | 0.1.0 | +#### SignInWithOAuthOptions + +| Prop | Type | Description | Since | +| ---------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------- | ----- | +| **`customParameters`** | SignInCustomParameter[] | Configures custom parameters to be passed to the identity provider during the OAuth sign-in flow. | 1.1.0 | +| **`scopes`** | string[] | Scopes to request from provider. | 1.1.0 | + + #### SignInWithCustomTokenOptions | Prop | Type | Description | Since | @@ -1175,23 +1201,6 @@ Callback to receive the user's sign-in state change notifications. -## FAQ - -1. **What does this plugin do?** - This plugin enables the use of [Firebase Authentication](https://firebase.google.com/docs/auth) in a Capacitor app. - It uses the Firebase SDK for [Java](https://firebase.google.com/docs/reference/android) (Android), [Swift](https://firebase.google.com/docs/reference/swift) (iOS) and [JavaScript](https://firebase.google.com/docs/reference/js). -1. **What is the difference between the web implementation of this plugin and the Firebase JS SDK?** - The web implementation of this plugin encapsulates the Firebase JS SDK and enables a consistent interface across all platforms. - You can decide if you prefer to use the web implementation or the Firebase JS SDK. -1. **What is the difference between the native and web authentication?** - For web authentication, the Firebase JS SDK is used. This only works to a limited extent on Android and iOS in the WebViews (see [here](https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html)). - For native authentication, the native SDKs from Firebase, Google, etc. are used. - These offer all the functionalities that the Firebase JS SDK also offers on the web. - However, after a login with the native SDK, the user is only logged in on the native layer of the app. - If the user should also be logged in on the web layer, additional steps are required (see [here](/packages/authentication/docs/firebase-js-sdk.md)). -1. **How can I use this plugin with the Firebase JavaScript SDK?** - See [here](/packages/authentication/docs/firebase-js-sdk.md). - ## Changelog See [CHANGELOG.md](/packages/authentication/CHANGELOG.md). diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java index 59a0f2fd..79ebf19e 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java @@ -78,7 +78,7 @@ public void applyActionCode(@NonNull String oobCode, @NonNull Runnable callback) } public void createUserWithEmailAndPassword(PluginCall call) { - boolean skipNativeAuth = this.config.getSkipNativeAuth(); + boolean skipNativeAuth = call.getBoolean("skipNativeAuth", this.config.getSkipNativeAuth()); if (skipNativeAuth) { call.reject(FirebaseAuthenticationPlugin.ERROR_EMAIL_SIGN_IN_SKIP_NATIVE_AUTH); return; @@ -232,7 +232,7 @@ public void signInWithYahoo(final PluginCall call) { } public void signInWithCustomToken(final PluginCall call) { - boolean skipNativeAuth = this.config.getSkipNativeAuth(); + boolean skipNativeAuth = call.getBoolean("skipNativeAuth", this.config.getSkipNativeAuth()); if (skipNativeAuth) { call.reject(FirebaseAuthenticationPlugin.ERROR_CUSTOM_TOKEN_SKIP_NATIVE_AUTH); return; @@ -259,7 +259,7 @@ public void signInWithCustomToken(final PluginCall call) { } public void signInWithEmailAndPassword(final PluginCall call) { - boolean skipNativeAuth = this.config.getSkipNativeAuth(); + boolean skipNativeAuth = call.getBoolean("skipNativeAuth", this.config.getSkipNativeAuth()); if (skipNativeAuth) { call.reject(FirebaseAuthenticationPlugin.ERROR_EMAIL_SIGN_IN_SKIP_NATIVE_AUTH); return; @@ -383,7 +383,7 @@ public void handleSuccessfulSignIn( @Nullable String accessToken, @Nullable AdditionalUserInfo additionalUserInfo ) { - boolean skipNativeAuth = this.config.getSkipNativeAuth(); + boolean skipNativeAuth = call.getBoolean("skipNativeAuth", this.config.getSkipNativeAuth()); if (skipNativeAuth) { JSObject signInResult = FirebaseAuthenticationHelper.createSignInResult( null, diff --git a/packages/authentication/docs/firebase-js-sdk.md b/packages/authentication/docs/firebase-js-sdk.md index 56e648e7..9a85a82c 100644 --- a/packages/authentication/docs/firebase-js-sdk.md +++ b/packages/authentication/docs/firebase-js-sdk.md @@ -5,13 +5,22 @@ ## How to use this plugin with the Firebase JavaScript SDK By default, this plugin signs the user in only on the native layer of the app. -In order to use the Firebase JavaScript SDK, a sign-in on the web layer is required. +In order to use the Firebase JavaScript SDK on Android and iOS, a sign-in on the web layer is required. To do this, follow these steps: 1. [Add Firebase to your JavaScript project](https://firebase.google.com/docs/web/setup) -1. Set the configuration option `skipNativeAuth` to `true` (see [here](/packages/authentication/README.md#configuration)). +1. Set the configuration option [`skipNativeAuth`](/packages/authentication/README.md#configuration) to `true` (sometimes you also need `false`, see [Quirks](#quirks)). 1. Sign in on the native layer, create web credentials and sign in on the web using [`signInWithCredential`](https://firebase.google.com/docs/reference/js/auth.md#signinwithcredential) (see [Examples](#examples)). +## Quirks + +When using the Firebase JS SDK on Android and iOS, you must be aware of the following: + +- **Apple Sign-In** works on Android and iOS only with `skipNativeAuth=true` (see [here](https://github.com/robingenz/capacitor-firebase-authentication/issues/41#issuecomment-884106449)). +- **Twitter Sign-In** works on iOS only with `skipNativeAuth=false` (see [here](https://github.com/robingenz/capacitor-firebase-authentication/issues/93#issuecomment-939459594)). + +**Note**: The [`skipNativeAuth`](/packages/authentication/README.md#configuration) configuration option can be overwritten for each plugin call individually (see `skipNativeAuth` paramter in [SignInOptions](/packages/authentication/README.md#signinoptions)). + ## Examples ```js diff --git a/packages/authentication/ios/Plugin/FirebaseAuthentication.swift b/packages/authentication/ios/Plugin/FirebaseAuthentication.swift index cb80b6fd..f04a7639 100644 --- a/packages/authentication/ios/Plugin/FirebaseAuthentication.swift +++ b/packages/authentication/ios/Plugin/FirebaseAuthentication.swift @@ -37,7 +37,8 @@ public typealias AuthStateChangedObserver = () -> Void } @objc func createUserWithEmailAndPassword(_ call: CAPPluginCall) { - if config.skipNativeAuth == true { + let skipNativeAuth = call.getBool("skipNativeAuth", config.skipNativeAuth) + if skipNativeAuth == true { call.reject(plugin.errorEmailSignInSkipNativeAuth) return } @@ -130,7 +131,8 @@ public typealias AuthStateChangedObserver = () -> Void } @objc func signInWithCustomToken(_ call: CAPPluginCall) { - if config.skipNativeAuth == true { + let skipNativeAuth = call.getBool("skipNativeAuth", config.skipNativeAuth) + if skipNativeAuth == true { call.reject(plugin.errorCustomTokenSkipNativeAuth) return } @@ -153,7 +155,8 @@ public typealias AuthStateChangedObserver = () -> Void } @objc func signInWithEmailAndPassword(_ call: CAPPluginCall) { - if config.skipNativeAuth == true { + let skipNativeAuth = call.getBool("skipNativeAuth", config.skipNativeAuth) + if skipNativeAuth == true { call.reject(plugin.errorEmailSignInSkipNativeAuth) return } @@ -266,10 +269,11 @@ public typealias AuthStateChangedObserver = () -> Void } func handleSuccessfulSignIn(credential: AuthCredential, idToken: String?, nonce: String?, accessToken: String?, displayName: String?) { - if config.skipNativeAuth == true { - guard let savedCall = self.savedCall else { - return - } + guard let savedCall = self.savedCall else { + return + } + let skipNativeAuth = savedCall.getBool("skipNativeAuth", config.skipNativeAuth) + if skipNativeAuth == true { let result = FirebaseAuthenticationHelper.createSignInResult(credential: credential, user: nil, idToken: idToken, nonce: nonce, accessToken: accessToken, additionalUserInfo: nil, displayName: displayName) savedCall.resolve(result) diff --git a/packages/authentication/src/definitions.ts b/packages/authentication/src/definitions.ts index 622ad7c1..ceb9b626 100644 --- a/packages/authentication/src/definitions.ts +++ b/packages/authentication/src/definitions.ts @@ -124,7 +124,9 @@ export interface FirebaseAuthenticationPlugin { * * @since 0.1.0 */ - signInWithApple(options?: SignInOptions): Promise; + signInWithApple( + options?: SignInOptions | SignInWithOAuthOptions, + ): Promise; /** * Starts the Custom Token sign-in flow. * @@ -157,25 +159,33 @@ export interface FirebaseAuthenticationPlugin { * * @since 0.1.0 */ - signInWithFacebook(options?: SignInOptions): Promise; + signInWithFacebook( + options?: SignInOptions | SignInWithOAuthOptions, + ): Promise; /** * Starts the GitHub sign-in flow. * * @since 0.1.0 */ - signInWithGithub(options?: SignInOptions): Promise; + signInWithGithub( + options?: SignInOptions | SignInWithOAuthOptions, + ): Promise; /** * Starts the Google sign-in flow. * * @since 0.1.0 */ - signInWithGoogle(options?: SignInOptions): Promise; + signInWithGoogle( + options?: SignInOptions | SignInWithOAuthOptions, + ): Promise; /** * Starts the Microsoft sign-in flow. * * @since 0.1.0 */ - signInWithMicrosoft(options?: SignInOptions): Promise; + signInWithMicrosoft( + options?: SignInOptions | SignInWithOAuthOptions, + ): Promise; /** * Starts the sign-in flow using a phone number. * @@ -193,19 +203,25 @@ export interface FirebaseAuthenticationPlugin { * * @since 0.1.0 */ - signInWithPlayGames(options?: SignInOptions): Promise; + signInWithPlayGames( + options?: SignInOptions | SignInWithOAuthOptions, + ): Promise; /** * Starts the Twitter sign-in flow. * * @since 0.1.0 */ - signInWithTwitter(options?: SignInOptions): Promise; + signInWithTwitter( + options?: SignInOptions | SignInWithOAuthOptions, + ): Promise; /** * Starts the Yahoo sign-in flow. * * @since 0.1.0 */ - signInWithYahoo(options?: SignInOptions): Promise; + signInWithYahoo( + options?: SignInOptions | SignInWithOAuthOptions, + ): Promise; /** * Starts the sign-out flow. * @@ -413,12 +429,47 @@ export interface SignInOptions { * Configures custom parameters to be passed to the identity provider during the OAuth sign-in flow. * * @since 0.1.0 + * @deprecated Use `SignInWithOAuthOptions` interface instead. */ customParameters?: SignInCustomParameter[]; /** * Scopes to request from provider. * * @since 0.3.1 + * @deprecated Use `SignInWithOAuthOptions` interface instead. + */ + scopes?: string[]; + /** + * Whether the plugin should skip the native authentication or not. + * Only needed if you want to use the Firebase JavaScript SDK. + * This value overwrites the configrations value of the `skipNativeAuth` option. + * If no value is set, the configuration value is used. + * + * **Note that the plugin may behave differently across the platforms.** + * + * `skipNativeAuth` cannot be used in combination with `signInWithCustomToken`, `createUserWithEmailAndPassword` or `signInWithEmailAndPassword`. + * + * Only available for Android and iOS. + * + * @since 1.1.0 + */ + skipNativeAuth?: boolean; +} + +/** + * @since 1.1.0 + */ +export interface SignInWithOAuthOptions extends SignInOptions { + /** + * Configures custom parameters to be passed to the identity provider during the OAuth sign-in flow. + * + * @since 1.1.0 + */ + customParameters?: SignInCustomParameter[]; + /** + * Scopes to request from provider. + * + * @since 1.1.0 */ scopes?: string[]; } @@ -444,7 +495,7 @@ export interface SignInCustomParameter { /** * @since 0.1.0 */ -export interface SignInWithPhoneNumberOptions { +export interface SignInWithPhoneNumberOptions extends SignInOptions { /** * The phone number to be verified. * @@ -470,7 +521,7 @@ export interface SignInWithPhoneNumberOptions { /** * @since 0.2.2 */ -export interface SignInWithEmailAndPasswordOptions { +export interface SignInWithEmailAndPasswordOptions extends SignInOptions { /** * The users email address. * @@ -527,7 +578,7 @@ export interface IsSignInWithEmailLinkResult { /** * @since 1.1.0 */ -export interface SignInWithEmailLinkOptions { +export interface SignInWithEmailLinkOptions extends SignInOptions { /** * The user's email address. * @@ -545,7 +596,7 @@ export interface SignInWithEmailLinkOptions { /** * @since 0.1.0 */ -export interface SignInWithCustomTokenOptions { +export interface SignInWithCustomTokenOptions extends SignInOptions { /** * The custom token to sign in with. *