如何将Firebase身份验证令牌传递到WebView并在Android上注册通知 [英] How to pass Firebase Auth token to webView and register for notifications on Android

本文介绍了如何将Firebase身份验证令牌传递到WebView并在Android上注册通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Firebase WebApp which provides info to a user. In addition to the app I need to send push notifications via Firebase Cloud Messaging to users with an Android App.

目标:用户应先登录到该应用程序,该应用程序既要注册它们以获取通知,又要通过WebView加载WebApp.

Goal: The user should have one login to the app which both registers them for notifications and loads the WebApp through a WebView.

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

Problem: I can't find an approach which achieves this with a single login. In every case I need to login once for the native app and then once again through the webView.

首先,为可能正在弄清楚事情的其他人提供一些参考:

First, some references for others who may be figuring things out:

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

Firebase Auth UI: https://firebase.google.com/docs/auth/android/firebaseui

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

Firebase DB: https://firebase.google.com/docs/database/android/read-and-write

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

Firebase Cloud Messaging: https://firebase.google.com/docs/cloud-messaging/android/topic-messaging

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

Background: I'm able to process each authentication separately using Firebase Auth UI to handle the notification auth natively and then process the webView authentication through the firebase server. This works but is a poor user experience. Since the native authentication already supplies a token I should, somehow, be able to skip the second stage and sign the user in directly. Here's the approaches I've tried:

第一种方法:

先进行本机登录,然后再进行Webapp登录(有效,但需要两次登录):通过遵循Firebase Auth UI教程,我可以成功登录:

Native sign-on followed by webapp sign on (working but requires two logins): By following the Firebase Auth UI tutorial I can complete a successful sign in:

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

'user'不为null,可用于从firebase数据库读取数据.然后根据FCM文档使用主题ID订阅主题.

'user' is not null and can be used to read data from firebase database. Topics IDs are then used to subscribe to topics per FCM documentation.

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

With notifications subscribed we then establish a connection to the webapp using this line:

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

第二种方法:

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

Pass user token with myWebView.loadUrl() (authorization is rejected) ...Based on this info: 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 有点在黑暗中射击......

*This seems to be the mostly likely way this is intended to work, maybe I need to add some code server-side to process the request explicitly rather than relying on the onStateChanged handler? Have also attempted using ?auth= and ?access_token= based on: https://firebase.google.com/docs/database/rest/auth#authenticate_with_an_id_token Sort of shooting in the dark here....

第三种方法:

打开webApp,并在授权完成后触发onAuthStateChanged.(处理程序似乎从未触发过.我怀疑没有FirebaseAuth对象会受到webView的影响)

Open webApp and trigger onAuthStateChanged when authorization is finished. (Handler never seems to fire. I suspect no FirebaseAuth object is impacted by 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("<​​a href="https://someproject.appspot.com/index.html" rel="noreferrer"> https://someproject.appspot.com/index.html );

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

似乎这里有一个最佳实践,在firebase教程中没有得到很好的记录.对于在Android上使用Firebase的人来说,这似乎也是一项典型任务.有人可以提供一种方法来注册通知主题并一次登录即可访问WebApp吗?我想念什么?

It seems like there is a best practise here that is not well documented in the firebase tutorials. This also seems like a typical task for someone using firebase on Android. Can someone offer an approach that registers the notification topics and accesses a webApp in one login? What am I missing?

预期结果将是一次登录,此后用户可以访问Web应用程序并注册为单独的推送通知.

The expected results are to have a single login, following which the user has access to the web app and is registered for individual push notifications.

推荐答案

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

Here is solution for Firebase Auth with WebView in React Native:

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注入)中可能需要类似的逻辑.

Similar logic might be required in Android (JS injection).

这篇关于如何将Firebase身份验证令牌传递到WebView并在Android上注册通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆