node.js - 在 Firestore 中使用通配符获取查询
问题描述
我想在 Firebase 中创建一个云功能,每当用户第一次登录时就会触发它。该函数需要将特定用户身份验证中的 UID 添加到 firestore 中已存在的特定文档中。问题是需要将 UID 添加到我不知道位置的文档中。我现在拥有的代码并没有完全做到这一点,但这是它出错的部分。简化后的数据库是这样的
organisations
[randomly generated id]
people
[randomly generated id] (in here, a specific document needs to be found based on known email
adress)
有多个不同的组织,不知道用户属于哪个组织。我想过使用通配符,如下所示:
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 进行硬编码确实会返回正确的值。此外,循环遍历每个组织不是一种选择,因为我需要有可能拥有很多组织。
许多解决方案都基于 Firestore 触发器,例如 onWrite,您可以在其中使用这样的通配符。但是,我认为在这种情况下这是不可能的
上述问题的解决方法:
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 });
}
这正是我所需要的,感谢大家的帮助!
解决方案
当用户登录到您的前端应用程序时,不可能触发 Cloud Function。Firebase 身份验证触发器中没有这样的触发器。
如果您想根据用户的某些特征(uid 或电子邮件)更新文档,您可以在用户登录后从应用程序执行此操作。
您在问题中提到,“在这里,需要根据已知的电子邮件地址找到特定的文档”。您应该首先构建一个查询来查找此文档,然后更新它,所有这些都来自应用程序。
另一种经典方法是为每个用户创建一个使用用户 uid 作为文档 ID 的特定文档,例如在users
集合中。然后很容易识别/查找此文档,因为一旦用户登录,您就知道他的 uid。
推荐阅读
- javascript - 我将一个元素推入了 Array[0] 位置,但是结果并没有达到我的预期。我的元素最终位于位置 Array[1],而不是 Array[0]
- python - 通过一对(行,列)值分配熊猫数据框
- html - 如何根据页面上的 div 数量重复/传播背景图像?
- docker - 如何在不指定 HTTP 端口的情况下访问 Docker 容器?
- c - 检查结构元素并将其与 C 中的用户输入进行比较
- alsa - 没有从 alsa 环回设备录制的音频
- javascript - 对象数组比较 2 个元素值
- c# - 2 SQL Server 中的 GridControl 和链接表
- ansible - 无法对 Ansible 需要创建的临时文件设置权限
- reactjs - React ant design 仅重置一个输入字段