icu*_*ham 7 android android-webview firebase firebase-authentication firebase-cloud-messaging
我有一个 Firebase WebApp,它为用户提供信息。除了应用程序之外,我还需要通过 Firebase Cloud Messaging 向使用 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 身份验证。这有效,但用户体验很差。由于本机身份验证已经提供了一个令牌,因此我应该能够跳过第二阶段并直接让用户登录。这是我尝试过的方法:
第一种方法:
本机登录,然后是 webapp 登录(工作但需要两次登录):按照 Firebase Auth UI 教程,我可以成功登录:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
Run Code Online (Sandbox Code Playgroud)
'user' 不为空,可用于从 firebase 数据库读取数据。然后使用主题 ID 订阅每个 FCM 文档的主题。
订阅通知后,我们然后使用以下行建立与 webapp 的连接:
myWebView.loadUrl("https://someproject.appspot.com/index.html");
Run Code Online (Sandbox Code Playgroud)
第二种方法:
使用 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);
...
Run Code Online (Sandbox Code Playgroud)
*这似乎是最有可能的工作方式,也许我需要添加一些代码服务器端来显式处理请求而不是依赖 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
}
...
Run Code Online (Sandbox Code Playgroud)
myWebView.loadUrl(" https://someproject.appspot.com/index.html ");
似乎这里有一个最佳实践,但在 firebase 教程中没有得到很好的记录。对于在 Android 上使用 firebase 的人来说,这似乎也是一项典型任务。有人可以提供一种注册通知主题并在一次登录中访问 webApp 的方法吗?我错过了什么?
预期的结果是进行一次登录,然后用户可以访问 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',
}}
/>
}Run Code Online (Sandbox Code Playgroud)
Android 中可能需要类似的逻辑(JS 注入)。
| 归档时间: |
|
| 查看次数: |
1545 次 |
| 最近记录: |