在Firestore中使用通配符获取查询 [英] Using wildcards in firestore get query

查看:71
本文介绍了在Firestore中使用通配符获取查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在firebase中创建一个云功能,该功能在用户首次登录时触发.该功能需要将特定用户的身份验证中的UID添加到Firestore中特定的,已经存在的文档中.问题是,UID需要添加到我不知道其位置的文档中.我现在拥有的代码不能完全做到这一点,但这是出错的部分.简化后的数据库看起来像这样

I want to create a cloud function in firebase that gets triggered whenever a user logs in for the first time. The function needs to add the UID from the authentication of the specific user to a specific, already existing document in firestore. The problem is that the UID needs to be added to a document of which I do not know the location. The code I have right now doesn't completely do that, but this is the part where it goes wrong. The database looks like this when simplified

organisations
    [randomly generated id]
        people
            [randomly generated id]  (in here, a specific document needs to be found based on known email 
                                      adress)

存在多个不同的组织,并且用户所属的组织是未知的.我想到使用通配符,如下所示:

There are multiple different organisations and it is unknown to which organisation the user belongs. I thought of using a wildcard, something like the following:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
console.log('function ready');
//Detect first login from user
//if(firebase.auth.UserCredential.isNewUser()){
if(true){
    //User is logged in for the first time
    //const userID = firebase.auth().currentUser.UID;
    //const userEmail = firebase.auth().currentUser.email;
    const userID = '1234567890';
    const userEmail = 'example@example.com';
    //Get email, either personal or work
    console.log('Taking a snapshot...');
    const snapshot = db.collection('organisations/{orgID}/people').get()
        .then(function(querySnapshot) {
            querySnapshot.forEach(function(doc) {
            console.log(doc.data());
        });
    });
}

出于测试目的,我注释掉了一些基于身份验证的行.我知道代码仍然可以运行,因为对orgID进行硬编码确实会返回正确的值.而且,通过每个组织循环不是一个选择,因为我需要有很多组织的可能性.

I commented out some authentication-based lines for testing purposes. I know the code still runs, because hardcoding the orgID does return the right values. Also, looping trough every organisation is not an option, because I need to have the possibility of having a lot of organisations.

许多解决方案都基于Firestore触发器,例如onWrite,您可以在其中使用通配符.但是,我认为在这种情况下是不可能的

A lot of solutions are based on firestore triggers, like onWrite, where you can use wildcards like this. However, I don't think that's possible in this case

上述问题的解决方案:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();

//Add UID to document in DB[FMIS-94]
//Detect first login from user
//if(firebase.auth.UserCredential.isNewUser()){
  if(true){
    //User is logged in for the first time
    //const userID = firebase.auth().currentUser.UID;
    //const userEmail = firebase.auth().currentUser.email;
    const userID = '1234567890';
    const userEmail = 'example@example.com';
    var docFound = false;
    //Get email, either personal or work
    console.log('Taking a snapshot...');
    //Test for work email
    const snapshot = db.collectionGroup('people').where('email.work', '==', userEmail).get()
      .then(function(querySnapshot){
        querySnapshot.forEach(function(doc){
          //work email found
          console.log('work email found');
          console.log(doc.data()); 
          docFound = true;
          const organisationID = doc.ref.parent.parent.id;
          writeUID(doc.id, userID, organisationID);  
        });
      });
  
    if(!docFound){
      //Test for personal email
      const snapshot = db.collectionGroup('people').where('email.personal', '==', userEmail).get()
      .then(function(querySnapshot){
        querySnapshot.forEach(function(doc){
          //personal email found
          console.log('personal email found');
          console.log(doc.data()); 
          const organisationID = doc.ref.parent.parent.id;
          writeUID(doc.id, userID, organisationID);  
        });
      });
    }
  }
  async function writeUID(doc, uid, organisationID){ 
    const res = db.collection(`organisations/${organisationID}/people`).doc(doc).set({
      userId: uid
    }, { merge: true });  
  } 

这正是我所需要的,谢谢大家的所有帮助!

This was exactly what I needed, thanks for all your help everyone!

推荐答案

我不确定我是否理解正确,但是如果要在所有 people 集合中进行搜索,那么无论组织文档,解决方案是为此使用集合组查询.

I'm not sure I understand you correctly, but if you want to search across all people collections not matter what organizations document they're under, the solution is to use a collection group query for that.

db.collectionGroup('people').get()
    .then(function(querySnapshot) {    
       querySnapshot.forEach(function(doc) {
        console.log("user: "+doc.id+" in organization: "+doc.ref.parent.parent.id);
    });
});

这将返回整个Firestore数据库中所有 people 集合的快照.

This will return a snapshot across all people collections in your entire Firestore database.

这篇关于在Firestore中使用通配符获取查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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