【发布时间】:2020-09-08 15:01:08
【问题描述】:
首先,我找到了很多关于这个问题的答案,建议在 Firestore 规则中删除 autentication。这当然不是我想要的。
我的 Firestore 规则是
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, update, write: if request.auth.uid != null;
}
}
}
而且我确实希望保留一定程度的授权。
我的安卓代码是:
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.firestore.FirebaseFirestore
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val db = FirebaseFirestore.getInstance()
val TAG = "MainActivity"
db.collection("transfer")
.get()
.addOnSuccessListener { result ->
for (document in result) {
Log.d(TAG, "${document.id} => ${document.data}")
}
}
.addOnFailureListener { exception ->
Log.w(TAG, "Error getting documents.", exception)
}
}
}
Android 项目包含直接从 Firestore 下载的 google-service.json
{
"project_info": {
"project_number": "7953 *** 50",
"firebase_url": "https://firetestjimis.firebaseio.com",
"project_id": "firetestjimis",
"storage_bucket": "firetestjimis.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:795 *** bb2ec8dc810f",
"android_client_info": {
"package_name": "com.example.demo"
}
},
"oauth_client": [
{
"client_id": "7953 **** sdu68ociuueir.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIza **** qHqOyrBsr_0cs_uq8"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "795 **** rkemu101gg0o.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
我的最终目标是实现与使用 Angular 但使用 Android/Kotlin 相同的目标。举例来说,我的工作 Angular 代码是:
app.component.ts
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { AngularFirestore, AngularFirestoreCollection } from '@angular/fire/firestore';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { map } from 'rxjs/operators';
import 'rxjs/Rx';
import { AngularFireAuth } from '@angular/fire/auth';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
public transfers: Observable<any[]>;
transferCollectionRef: AngularFirestoreCollection<any>;
constructor(public auth: AngularFireAuth, public db: AngularFirestore) {
this.listenSingleTransferWithToken();
}
async listenSingleTransferWithToken() {
await this.auth.signInWithCustomToken("eyJ **** a custom token **** bdaG1Q");
this.transferCollectionRef = this.db.collection<any>('transfer', ref => ref.where("id", "==", "1"));
this.transfers = this.transferCollectionRef.snapshotChanges().map(actions => {
return actions.map(action => {
const data = action.payload.doc.data();
const id = action.payload.doc.id;
return { id, ...data };
});
});
环境.ts
export const environment = {
production: false,
firebaseConfig: {
apiKey: "AI yyy ihK3xs",
authDomain: "firetestjimis.firebaseapp.com",
databaseURL: "https://firetestjimis.firebaseio.com",
projectId: "firetestjimis",
storageBucket: "firetestjimis.appspot.com",
messagingSenderId: "79 www 350",
appId: "1:xxx dc810f"
}
};
}
所以我的直截了当的问题是:我缺少什么才能使上面的 kotlin 代码正确识别?也许这与 Angular 的想法相同,我只需要在调用期间添加一个自定义令牌,但如何在 Android/kotlin 中做到这一点?
***已编辑
NodeJs 服务器提供了一个 CustomToken 成功地在 Angular 上运行,但我想念在 Android/Kotlin 中如何做同样的事情
const admin = require('firebase-admin');
exports.serviceAccount = {
"type": "service_account",
"project_id": "firetestjimis",
"private_key_id": "ecfc6 *** e6661fd05923",
"private_key": "-----BEGIN PRIVATE KEY-----\ *** REMOVED *** ==\n-----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk-fg6p9@firetestjimis.iam.gserviceaccount.com",
"client_id": "1024 *** 38150",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fg6p9%40firetestjimis.iam.gserviceaccount.com"
}
admin.initializeApp({
credential: admin.credential.cert(exports.serviceAccount)
});
var uid = "NSB *** 4DRo2"; //copied from https://console.firebase.google.com/project/firetestjimis/authentication/users
var claim = {
control: true
};
admin.auth().createCustomToken(uid)
.then(function (customToken) {
console.log(customToken)
})
.catch(function (error) {
console.log("Error creating custom token:", error);
});
【问题讨论】:
-
您在 Android 应用程序中的何处验证用户身份?
-
@RosárioPereiraFernandes,我不打算在 Adroid 中对用户进行身份验证。它将从内部端点接收 CustomToken。内部端点是指托管在我们的 DataCenter 中的 NodeJs 服务器,它将响应我们的 Android 应用程序,然后,使用这个 CustonToken,应用程序可以开始监听一个集合文档(您可以在上面的 Angular 中看到它的工作)。我编辑了我的问题,添加了提供 CustomToken 的 NodeJ,尽管我认为它并不相关。基于相同的 Angular 方法,你知道如何在 Android/Kotlin 中“signInWithCustomToken”然后“snapshotChanges()”吗?
-
@RosárioPereiraFernandes 我刚刚从我的 Android Studio 添加了一个打印屏幕,其中显示了 CustomToken 已验证并且已登录。但是如何监听/观察/快照更改集合文档?
标签: android angular firebase kotlin google-cloud-firestore