在 Cordova 中使用 OAuth 提供方进行身份验证

通过 Firebase JS SDK,您可以让 Firebase 用户在 Cordova 环境中使用任何受支持的 OAuth 提供方进行身份验证。您可以通过以下方法集成任何受支持的 OAuth 提供方:使用 Firebase SDK 执行登录流程;或者手动执行 OAuth 流程,并将生成的 OAuth 凭据传递给 Firebase。

为 Cordova 设置 Firebase Authentication

  1. 将 Firebase 添加到您的 JavaScript 项目。添加 Firebase 代码段时,请注意 authDomain 配置变量,它应类似于 my-app.firebaseapp.com。如果使用的是自定义网域而非 Firebase 预配的 firebaseapp.com 网域,则应改用该自定义网域。

  2. 如需设置 Android 应用,请将您的 Android 应用添加到 Firebase 控制台并输入您的应用的详细信息。您不需要生成的 google-services.json

  3. 如需设置 iOS 应用,请创建一个 iOS 应用并将其添加到 Firebase 控制台。以后安装自定义网址架构插件时,您将需要添加该 iOS 软件包 ID。

  4. 启用 Firebase Dynamic Links:

    1. Firebase 控制台中,打开 Dynamic Links 部分。
    2. 如果您尚未接受 Dynamic Links 条款,并且也未创建动态链接网域,请立即完成这些操作。

      如果您已经创建了动态链接网域,请记下此网域。动态链接网域通常采用如下格式:

      example.page.link

      配置 Apple 或 Android 应用以拦截传入链接时,您需要用到此值。

  5. 在 Firebase 控制台中启用 Google 登录:

    1. Firebase 控制台中,打开 Auth 部分。
    2. 登录方法标签页中,启用 Google 登录方法并点击保存
  6. 在 Cordova 项目中安装所需的插件。

    # Plugin to pass application build info (app name, ID, etc) to the OAuth widget.
    cordova plugin add cordova-plugin-buildinfo --save
    # Plugin to handle Universal Links (Android app link redirects)
    cordova plugin add cordova-universal-links-plugin-fix --save
    # Plugin to handle opening secure browser views on iOS/Android mobile devices
    cordova plugin add cordova-plugin-browsertab --save
    # Plugin to handle opening a browser view in older versions of iOS and Android
    cordova plugin add cordova-plugin-inappbrowser --save
    # Plugin to handle deep linking through Custom Scheme for iOS
    # Substitute *com.firebase.cordova* with the iOS bundle ID of your app.
    cordova plugin add cordova-plugin-customurlscheme --variable \
        URL_SCHEME=com.firebase.cordova --save
    
  7. 将以下配置添加到您的 Cordova config.xml 文件中,其中 AUTH_DOMAIN 是步骤 (1) 中的网域,DYNAMIC_LINK_DOMAIN 是步骤 (3c) 中的网域。

    <universal-links>
        <host name="DYNAMIC_LINK_DOMAIN" scheme="https" />
        <host name="AUTH_DOMAIN" scheme="https">
            <path url="/__/auth/callback"/>
        </host>
    </universal-links>
    

    示例配置可能如下所示:

    <universal-links>
        <host name="example.page.link" scheme="https" />
        <host name="example-app.firebaseapp.com" scheme="https">
            <path url="/__/auth/callback"/>
        </host>
    </universal-links>
    

    如果使用自定义网域 auth.custom.domain.com,请将 my-app.firebaseapp.com 替换为该网域。

    对于 Android 应用,launchMode 应该采用 singleTask

    <preference name="AndroidLaunchMode" value="singleTask" />
    

使用 Firebase SDK 处理登录流程

  1. Firebase Authentication 依赖于 deviceReady 事件来准确确定当前的 Cordova 环境。请确保在该事件触发后初始化 Firebase 应用实例。

  2. 创建 Google 提供方对象实例:

    Web 模块化 API

    import { GoogleAuthProvider } from "firebase/auth/cordova";
    
    const provider = new GoogleAuthProvider();

    Web 命名空间型 API

    var provider = new firebase.auth.GoogleAuthProvider();
  3. 使用 signInWithRedirect 通过 Google 提供方对象进行 Firebase 身份验证。请注意,Cordova 不支持 signInWithPopup

    Web 模块化 API

    import { getAuth, signInWithRedirect, getRedirectResult, GoogleAuthProvider } from "firebase/auth/cordova";
    
    const auth = getAuth();
    signInWithRedirect(auth, new GoogleAuthProvider())
      .then(() => {
        return getRedirectResult(auth);
      })
      .then((result) => {
        const credential = GoogleAuthProvider.credentialFromResult(result);
    
        // This gives you a Google Access Token.
        // You can use it to access the Google API.
        const token = credential.accessToken;
    
        // The signed-in user info.
        const user = result.user;
        // ...
      }).catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
      });

    Web 命名空间型 API

    firebase.auth().signInWithRedirect(provider).then(() => {
      return firebase.auth().getRedirectResult();
    }).then((result) => {
      /** @type {firebase.auth.OAuthCredential} */
      var credential = result.credential;
    
      // This gives you a Google Access Token.
      // You can use it to access the Google API.
      var token = credential.accessToken;
      // The signed-in user info.
      var user = result.user;
      // ...
    }).catch((error) => {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
    });
  4. 如需应对登录操作完成之前应用活动即已销毁的情况,请在应用加载时调用 getRedirectResult

    Web 模块化 API

    import { getAuth, getRedirectResult, GoogleAuthProvider } from "firebase/auth/cordova";
    
    const auth = getAuth();
    getRedirectResult(auth)
      .then((result) => {
        const credential = GoogleAuthProvider.credentialFromResult(result);
        if (credential) {        
          // This gives you a Google Access Token.
          // You can use it to access the Google API.
          const token = credential.accessToken;
          // The signed-in user info.
          const user = result.user;
          // ...
        }
      })
      .catch((error) => {
        // Handle Errors here.
        const errorCode = error.code;
        const errorMessage = error.message;
      });

    Web 命名空间型 API

    firebase.auth().getRedirectResult().then((result) => {
      if (result.credential) {
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // This gives you a Google Access Token.
        // You can use it to access the Google API.
        var token = credential.accessToken;
        // The signed-in user info.
        var user = result.user;
        // ...
      }
    }).catch((error) => {
      // Handle Errors here.
      var errorCode = error.code;
      var errorMessage = error.message;
    });

    您可使用同一机制通过 linkWithRedirect 来关联新的提供方,或者使用 reauthenticateWithRedirect 通过现有提供方重新进行身份验证。