如何将 Firebase 身份验证令牌传递给 webView 并在 Android 上注册通知

2023-11-24

我有一个 Firebase WebApp,它向用户提供信息。除了应用程序之外,我还需要通过 Firebase 云消息传递向使用 Android 应用程序的用户发送推送通知。

目标:用户应该一次登录到应用程序,既可以注册通知,又可以通过 WebView 加载 WebApp。

问题:我找不到通过单次登录实现此目的的方法。在每种情况下,我都需要登录一次本机应用程序,然后通过 webView 再次登录。


首先,为其他可能正在解决问题的人提供一些参考:

Firebase 身份验证用户界面:https://firebase.google.com/docs/auth/android/firebaseui

Firebase 数据库:https://firebase.google.com/docs/database/android/read-and-write

Firebase 云消息传递:https://firebase.google.com/docs/cloud-messaging/android/topic-messaging

背景:我可以使用 Firebase Auth UI 单独处理每个身份验证,以本地处理通知身份验证,然后通过 firebase 服务器处理 webView 身份验证。这可行,但用户体验很差。由于本机身份验证已经提供了令牌,因此我应该能够跳过第二阶段并直接让用户登录。这是我尝试过的方法:


第一种方法:

本机登录,然后是 Web 应用程序登录(可以工作,但需要两次登录): 通过遵循 Firebase Auth UI 教程,我可以成功完成登录:

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

'user' 不为空,可用于从 firebase 数据库读取数据。然后,主题 ID 用于订阅每个 FCM 文档的主题。

订阅通知后,我们可以使用以下行建立与 Web 应用程序的连接:

myWebView.loadUrl("https://someproject.appspot.com/index.html");

第二种方法:

使用 myWebView.loadUrl() 传递用户令牌(授权被拒绝) ...基于此信息:https://firebase.google.com/docs/cloud-messaging/auth-server

我期望与此类似的东西:

...

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

  if (user != null) {

  //get the user id token

  user.getIdToken(true).addOnCompleteListener(new 
  OnCompleteListener<GetTokenResult>() {

    public void onComplete(@NonNull Task<GetTokenResult> task) {

      if (task.isSuccessful()) {

        //here is the idToken

        String idToken = task.getResult().getToken();

  }}}}

HashMap<String, String> map = new HashMap<String, String>();

String bearer = "Bearer " + idToken;

//Create header of the form "Authorization: Bearer <token>"

map.put("Authorization",bearer);

myWebView.loadUrl("https://someproject.appspot.com/index.html", map);

...

*这似乎是最有可能的工作方式,也许我需要在服务器端添加一些代码来显式处理请求,而不是依赖 onStateChanged 处理程序?还尝试使用 ?auth= 和 ?access_token= 基于:https://firebase.google.com/docs/database/rest/auth#authenticate_with_an_id_token有点像在黑暗中拍摄......

第三种方法:

打开webApp,授权完成后触发onAuthStateChanged。 (处理程序似乎永远不会触发。我怀疑没有 FirebaseAuth 对象受到 webView 的影响)

...
//Register a FirebaseAuth Listener

FirebaseAuth.AuthStateListener mAuthListener = new FirebaseAuth.AuthStateListener() {

  @Override

  public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {

    FirebaseUser user = firebaseAuth.getCurrentUser();

    if (user != null) {

      //Register notification subscriptions per tutorial

    }
...

myWebView.loadUrl("https://someproject.appspot.com/index.html");


似乎这里有一个最佳实践,但在 firebase 教程中没有详细记录。对于在 Android 上使用 firebase 的人来说,这似乎也是一项典型任务。有人可以提供一种注册通知主题并在一次登录中访问 web 应用程序的方法吗?我缺少什么?

预期结果是单次登录,然后用户就可以访问 Web 应用程序并注册单个推送通知。


以下是 React Native 中使用 WebView 进行 Firebase Auth 的解决方案:

import React from 'react'
import WebView from 'react-native-webview'

export default function HomeScreen(props) {
  // props.user represents firebase user
  const apiKey = props.user.toJSON().apiKey
  const authJS = `
        if (!("indexedDB" in window)) {
          alert("This browser doesn't support IndexedDB")
        } else {
          let indexdb = window.indexedDB.open('firebaseLocalStorageDb', 1)
          indexdb.onsuccess = function() {
            let db = indexdb.result
            let transaction = db.transaction('firebaseLocalStorage', 'readwrite')
            let storage = transaction.objectStore('firebaseLocalStorage')
            const request = storage.put({
              fbase_key: "firebase:authUser:${apiKey}:[DEFAULT]",
              value: ${JSON.stringify(props.user.toJSON())}
            });
          }
        }  
      `
  return <WebView
    injectedJavaScriptBeforeContentLoaded={authJS}
    source={{
      uri: 'http://192.168.1.102:3000',
      baseUrl: 'http://192.168.1.102:3000',
    }}
  />
}

Android 中可能需要类似的逻辑(JS 注入)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 Firebase 身份验证令牌传递给 webView 并在 Android 上注册通知 的相关文章