当前位置: 首页 > 知识库问答 >
问题:

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

通骁
2023-03-14

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

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

问题:我找不到一种只需一次登录就能实现这一点的方法。在任何情况下,我都需要登录一次本地应用程序,然后通过webView再次登录。

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

火力基础身份验证用户界面:https://firebase.google.com/docs/auth/android/firebaseui

火力基地数据库:https://firebase.google.com/docs/database/android/read-and-write

Firebase云消息:https://firebase . Google . com/docs/Cloud-Messaging/Android/topic-Messaging

背景:我能够使用Firebase身份验证UI分别处理每个身份验证,以本地方式处理通知身份验证,然后通过Firebase服务器处理webView身份验证。这有效,但用户体验不佳。由于本机身份验证已经提供了令牌,因此我应该能够以某种方式跳过第二阶段并直接登录用户。以下是我尝试过的方法:

第一种方法:

本机登录,然后是webapp登录(正常工作,但需要两次登录):通过遵循Firebase身份验证UI教程,我可以完成成功登录:

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

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

订阅通知后,我们使用以下行建立与webapp的连接:

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= and?access _ token = based:https://firebase . Google . com/docs/database/rest/auth # authenticate _ with _ an _ id _ token这里有点瞎猜....

第三种方法:

打开webApp并在授权完成时触发onAuthStateChanged。(处理程序似乎从未触发。我怀疑没有Firebase Auth对象受到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的人来说,这似乎也是一个典型的任务。有人可以提供一种在一次登录中注册通知主题并访问 webApp 的方法吗?我错过了什么?

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

共有2个答案

敖永丰
2023-03-14

一种方法是使用Android Google Auth SDK在应用程序中本地登录,然后将Google令牌传递给Webview,以便Firebase可以通过< code > Auth . signinwithcredential()使用它。

它可能适用于其他提供商,但这是我在Android上使用Google身份验证的方式:

Android系统:

val gso =
    GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
      .requestIdToken(clientId)
      .requestEmail()
      .build()
val googleSignInClient = GoogleSignIn.getClient(activity, gso)

activity.startActivityForResult(
        googleSignInClient.signInIntent,
        object : ActivityWithResultListener.OnActivityResultListener {
          override fun onActivityResult(resultCode: Int, data: Intent?) {
            if (data != null) {
              val credential = GoogleAuthProvider.getCredential(account.idToken!!, null)
              idToken = account.idToken!!

              // Then pass the token to your webview via a JS interface
            }
          }
       }
)


网页:

const idTokenFromApp = AndroidBridge.getAuthToken(); // This is the idToken from the Android code above
if (idTokenFromApp) {
    // from https://firebase.google.com/docs/auth/web/google-signin
    // Build Firebase credential with the Google ID token.
    // https://firebase.google.com/docs/reference/js/v8/firebase.auth.GoogleAuthProvider#static-credential
    const credential = firebase.auth.GoogleAuthProvider.credential(idTokenFromApp);

    // Sign in with credential from the Google user.
    firebase.auth.signInWithCredential(credential).catch((error) => {
      // Handle Errors here.
      const errorCode = error.code;
      const errorMessage = error.message;

      logError(`Error logging in: ${errorCode} ${errorMessage} token: ${idTokenFromApp}`, error);
    });
}

经昱
2023-03-14

以下是使用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',
    }}
  />
}
 类似资料:
  • 是否有一种方法可以在我的服务器上验证Firebase注册令牌,而无需往返Firebase服务器?我只是想知道它们是否有效,不一定是有效的。

  • 我有一个从https://github.com/Azure-Samples/ms-identity-blazor-wasm/tree/main/WebApp-graph-user/Call-MSGraph.创建的blazor网络组装项目 它基本上是您使用时创建的项目。用于Blazor应用程序的net core模板,该应用程序通过AD B2B进行身份验证 然后我能够调用graph。用户登录时的api

  • 我在laravel上有自己的登录概念。现在我想让它成为第三方登录解决方案。所以我必须了解很多事情。所以请告诉我 为什么我们总是在Get和Post方法的头上传递身份验证令牌? 为什么不在直接url(查询字符串)上? 这有什么优点和缺点?

  • 我有一个REST Jersey web服务。 php中基于令牌的身份验证 它在答复中提到; “然后它发送此令牌和请求的某些特征的哈希来验证请求,例如sha1(令牌+时间戳+请求URL+请求正文)。您的服务器可以对此进行验证,而客户端不必在每个请求上以纯文本发送令牌。” 另一个问题是,一旦服务器接收到这个令牌的哈希值(包括时间戳和用户ID等),服务器如何在没有存储令牌的查找表或数据库的情况下从这个令

  • 大家好,我对FireBase创建用户和注册用户有问题。下面是注册和登录的代码。我得到空指针异常,无法理解原因。。初始化完成了,但经过了这么多天的努力,还是弄不明白。 注册: 正在发布注册活动的日志错误: java.lang.com.google.android.gms.internal.zzdvv.zzb(未知来源)在com.google.android.gms.internal.zzdwc.zz

  • 我有一个LaravelAPI(实际上是LumenAPI)服务于VueJS前端。Vue应用程序允许用户登录到谷歌。然后将Google令牌发送回Lumen API,后者使用Google验证令牌,然后验证电子邮件地址是否为有效用户。然后它生成一个令牌,与用户一起存储在数据库中,并返回用户对象。 我没有使用Passport或jwt auth之类的东西。那么现在,我如何使用默认的Auth中间件来验证(现在已