【问题标题】:Issues getting data from specific user (firestore rules)从特定用户获取数据的问题(firestore 规则)
【发布时间】:2020-01-14 22:58:14
【问题描述】:

嘿,我在从特定用户那里获取数据时遇到问题。我在这个集合中有一个“订单”集合,我保存了创建订单的用户的用户 ID。我可以获得所有订单,但我如何只从该用户那里获得订单?如果我将 Firestore 规则更改为: allow read, write: if resource.data.userID == request.auth.uid; 我不再收到任何“订单”。

我尝试改变规则,当我检查授权用户时,我得到了整个列表。但仍然不是那个特定的。

export class BestellungService {
  pizza;
  order: Order;

  private ordersCollection: AngularFirestoreCollection<Order>;
  private orders: Observable<Order[]>;


  constructor(private NavController: NavController,db: AngularFirestore) {
    this.ordersCollection = db.collection<Order>("Bestellungen");

    this.orders = this.ordersCollection.snapshotChanges().pipe(
      map(actions => {
        return actions.map(a => {
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return {id, ...data};
        })
      })
    )


   }
 getOrders(){
    return this.orders;
  }

  getOrder(id){
    return this.ordersCollection.doc<Order>(id).valueChanges();
  }


  updateOrder(orders: Order, id: string){
    return this.ordersCollection.doc(id).update(orders);
  }

  addOrder(order: Order){
    //var pizzenList = order.pizzen.map((obj)=> {return Object.assign({}, obj)});
    const newOrder: Order ={
      userID: order.userID,
      status: order.status,
      pizzen: order.pizzen,
      createdAt: new Date().getTime(),
      total: order.total,
      total_string: order.total_string,
      location: order.location
    }
    return this.ordersCollection.add(newOrder);
  }

  removeOrder(id){
    return this.ordersCollection.doc(id).delete();
  }
}

这就是我添加/获取订单的方式。

export class HomePage implements OnInit {
  orders: Order[];
  userEmail: string;
  userID: string;
  subscription;
  constructor(
    private navCtrl: NavController,
    private authService: AuthenticateService,
    private BestellungService: BestellungService
  ) {}

  ngOnInit(){
    console.log("HomePage ngOnInit"); 

    if(this.authService.userDetails()){
      this.userEmail = this.authService.userDetails().email;
      this.userID = this.authService.userDetails().uid;
      let subscription = this.BestellungService.getOrders().subscribe(res=>{
        this.orders = res;
        console.log("RES: ",res);
        console.log("bestellungen: ",this.orders);
      });
      this.subscription = subscription;
    }else{
      this.navCtrl.navigateBack('');
    }


  }
}

这就是我让它们显示的方式

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /Bestellungen/{bestellungID}{
    allow read, write: if resource.data.userID == request.auth.uid;
    //allow read, write: if request.auth.uid != null;
    }
    match /users/{userID}{
    allow read, write: if userID == request.auth.uid;
    }
  }

  function getUserData(){
  return get(/database/$(database)/documents/users/$(request.auth.uid)).data;
  }
} 

这些是我期望的规则。我用模拟器尝试了规则并获得了许可,但它在我的代码中不起作用。

我的预期结果是来自当前登录用户的订单列表。 错误:

core.js:9110 ERROR FirebaseError: Missing or insufficient permissions.
    at new FirestoreError (http://localhost:8100/vendor.js:115916:28)
    at JsonProtoSerializer.push../node_modules/@firebase/firestore/dist/index.cjs.js.JsonProtoSerializer.fromRpcStatus (http://localhost:8100/vendor.js:130570:16)
    at JsonProtoSerializer.push../node_modules/@firebase/firestore/dist/index.cjs.js.JsonProtoSerializer.fromWatchChange (http://localhost:8100/vendor.js:131067:44)
    at PersistentListenStream.push../node_modules/@firebase/firestore/dist/index.cjs.js.PersistentListenStream.onMessage (http://localhost:8100/vendor.js:127017:43)
    at http://localhost:8100/vendor.js:126946:30
    at http://localhost:8100/vendor.js:126986:28
    at http://localhost:8100/vendor.js:117254:20
    at ZoneDelegate.invoke (http://localhost:8100/polyfills.js:3365:26)
    at Zone.run (http://localhost:8100/polyfills.js:3130:43)
    at http://localhost:8100/polyfills.js:3861:36

【问题讨论】:

    标签: angular ionic-framework google-cloud-firestore firebase-security


    【解决方案1】:

    重要的是要认识到安全规则不是过滤器。您不能依赖安全规则来修改查询结果集。如果任何文档可能与安全规则的约束不匹配,则整个查询将失败。这意味着您的查询只需要请求已知通过规则的文档。

    您的规则要求文档上的用户 ID 与用户的 UID 匹配:

    match /Bestellungen/{bestellungID}{
      allow read, write: if resource.data.userID == request.auth.uid;
    }
    

    这意味着此查询每次都会失败,因为它请求的文档可能具有任何用户 ID:

    this.ordersCollection = db.collection<Order>("Bestellungen");
    

    您需要做的是仅查询当前用户的文档:

    this.ordersCollection = db.collection<Order>("Bestellungen")
        .where("userID", "==", uid);
    

    我不熟悉 Angular,所以语法可能不正确。但关键是客户端上的查询必须符合规则,否则将永远被拒绝。

    【讨论】:

      猜你喜欢
      • 2023-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 2021-06-21
      • 2021-06-26
      • 1970-01-01
      相关资源
      最近更新 更多