首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >FirebaseError:缺少或不足的权限。如何在观察特定文档的同时添加idToken

FirebaseError:缺少或不足的权限。如何在观察特定文档的同时添加idToken
EN

Stack Overflow用户
提问于 2020-04-22 00:21:56
回答 1查看 1.2K关注 0票数 1

我对实时通知的代码进行了编码。我的意思是,它一直在观察,很快任何集合字段都会被更新,它会被加载到角度页面中。

app.component.ts

代码语言:javascript
运行
复制
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { AngularFirestore } from '@angular/fire/firestore';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  public transfers: Observable<any[]>;

  constructor(db: AngularFirestore) {
    this.transfers = db.collection('/transfer').valueChanges();
  }

}

app.component.html

代码语言:javascript
运行
复制
<ul>
  <li *ngFor="let transfer of transfers | async">
    <pre>{{ transfer | json }}</pre>
  </li>
</ul>

我的问题是,我不知道如何添加idToken,同时使用db.collection()、.valueChanges()或snapshotChanges()进行观察。嗯,我知道如何从自定义令牌在应用程序之外生成idToken,对于这个问题,我只想关注如何在“侦听”特定文档的valueChanges()或snapshotChanges()的同时添加这样的idToken。假设每个文档都是一个只对单个用户感兴趣的不同事务。

如果我将Firestore规则更改为“允许对所有人读取”,则上面的代码可以正常工作,但我希望找到某种方式,如果它通过idToken,只允许角度读取,并且在此基础上,观察单个文档的更改,而不是像上面的代码那样观察整个集合中的所有文档。

这里有一些触须,只是为了举例说明我在尝试什么。我不知道如何在其中任何一个中添加idToken。我还添加了一个我想象的没有AngularFire的例子。我想我对以下三点感到困惑:

  • ,一些非常基本的想法,如何观察/侦听单个文档,

  • ,如何添加类似于curl/postman
  • 的idToken --听/观察单个文档是不可能的。我必须观察整个收集和过滤。

暂定1:

代码语言:javascript
运行
复制
this.uniqueTransfer = db.collection('/transfer',
  ref => ref.where("id", "==", "1"))
  .snapshotChanges().pipe(map(actions => actions.map(a => a.payload.doc.data()))
  );;

暂定2:

代码语言:javascript
运行
复制
this.uniqueTransfer = db.collection('/transfer', ref => ref.where("id", "==", "1")).snapshotChanges().pipe(
  map(actions => actions.map(a => {
    const data = a.payload.doc.data();
    return { data };
  }))

暂定3:

代码语言:javascript
运行
复制
db.doc(`transfer/Wsj0dysyHHok3xupwDhD`) //this is the id copied from Firebase console
  .snapshotChanges()
  .pipe()
  .subscribe();

不含AngularFire的暂定4

代码语言:javascript
运行
复制
constructor(private http: HttpClient) {
  this.getTranfers();
}

public getTranfers() {

  const headers = { 'Authorization': 'valid idtoken working with curl' }
  const body = JSON.stringify({
    "structuredQuery": {
      "where": {
        "fieldFilter": {
          "field": { "fieldPath": "id" },
          "op": "EQUAL",
          "value": { "stringValue": "4" }
        }
      },
      "from": [{ "collectionId": "transfer" }]
    }
  })

  this.http.post<any>('https://firestore.googleapis.com/v1/projects/firetestjimis/databases/(default)/documents:runQuery', body, { headers }).subscribe(data => {
    this.uniqueTransfer = data;
  })
}

预期的行为是侦听一个特定的文档被更改并更新前端,例如:

代码语言:javascript
运行
复制
<div>{{(uniqueTransfer|async)?.status}}</div>

最后,如果它在这里添加,我可以使用这个curl查询单个文档。很明显,它不是在听/看这份文件。它只是收回了它。

代码语言:javascript
运行
复制
curl --location --request POST 'https://firestore.googleapis.com/v1/projects/firetestjimis/databases/(default)/documents:runQuery' \
--header 'Authorization: Bearer certain idToken resulted from a Custom Token' \
--header 'Content-Type: application/json' \
--data-raw '{
"structuredQuery": {
    "where" : {
        "fieldFilter" : { 
        "field": {"fieldPath": "id"}, 
        "op":"EQUAL", 
        "value": {"stringValue": "1"}
        }
    },
    "from": [{"collectionId": "transfer"}]
    }
}'

*编辑后,gso_Gabriel的两项建议。

第一项建议)

我试着跟着https://github.com/angular/angularfire/issues/2109。这似乎是对新特性的建议,而不是目前的一种选择。顺便说一句,我试过:

代码语言:javascript
运行
复制
this.transfers = db.doc<any>(`transfer/sDme6IRIi4ezfeyfrU7y`).valueChanges();

sDme6IRIi4ezfeyfrU7y表示特定文档,但我从transfer集合中获得了所有文档(与this.transfers =db.collection(‘/transfer’).valueChanges()相同);

第二项建议)

代码语言:javascript
运行
复制
import { map } from 'rxjs/operators';
import 'rxjs/Rx';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  public transfers: Observable<any[]>;
  uniqueTransfer: any;

  transferCollectionRef: AngularFirestoreCollection<any>;

  constructor(db: AngularFirestore) {

    this.transferCollectionRef = 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();// as Todo;
        const id = action.payload.doc.id;
        return { id, ...data };
      });
    });
}

这个成功了。我可以看到过滤器“哪里”被应用(.参考=> ref.where("id","==","1")

现在,我错过了如何使用自定义Tokem产生的idToken。我想它必须以某种方式存在,就像我们对HttpClient所做的一样(请参阅我上面的试探性4,了解什么是使用头的通用方法)。

*如果它在这里添加了一些内容,即使是github上发布的类似问题也没有得到任何评论,除了有人说正在寻找相同的答案( https://github.com/angular/angularfire/issues/2419 )

*感谢gstvg的最终解决方案

代码语言:javascript
运行
复制
export class AppComponent {
  public transfers: Observable<any[]>;

  transferCollectionRef: AngularFirestoreCollection<any>;

  constructor(public auth: AngularFireAuth, public db: AngularFirestore) {
    this.listenSingleTransferWithToken();
  }

  async listenAllTransfersWithToken() {
    await this.auth.signInWithCustomToken("eyJh...w8l-NO-rw");
    this.transfers = this.db.collection('/transfer').valueChanges();
  }

  async listenSingleTransferWithToken() {
    await this.auth.signInWithCustomToken("eyJ...w8l-NO-rw");
    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 };
      });
    });

  }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-01 20:56:56

防火墙客户端auth由firebase auth处理,因此,要进行身份验证调用,必须使用firebase.auth.signinWithCustomToken(customToken):在后端生成自定义令牌,在前端使用firebase auth进行身份验证。

代码语言:javascript
运行
复制
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { AngularFireAuth } from '@angular/fire/auth';
import { auth } from 'firebase/app';
import { AngularFirestore } from '@angular/fire/firestore';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  public transfers: Observable<any[]>;

  constructor(db: AngularFirestore, public auth: AngularFireAuth) {
    await auth.signinWithCustomToken(customToken);
    this.transfers = db.collection('/transfer').valueChanges();
  }

}

https://firebase.google.com/docs/reference/js/firebase.auth.Auth#signinwithcustomtoken

https://github.com/angular/angularfire/blob/master/docs/auth/getting-started.md

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61355351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档