我正在使用 Angular 和 firebase 创建一个应用程序。我想在该集合中创建一个名为 PETS 的集合,文档 ID 将是当前登录的用户 UID。在该文档中,我想根据我的表单值创建具有随机 ID 的文档。
-|pets
-|userId
-|RandomId which contains all the form values
-|RandomId which contains all the form values
我现在正在使用这个方法。请告诉我这里需要进行哪些更改。此方法创建与当前用户具有相同 ID 的集合。但它不会使用用户 ID 在父文档中创建单独的文档。另外,我想用随机 ID 循环遍历这些文档,并在前面显示 PETS 列表。
addPet(ownerName, PetName, type, breed, size){
let user = this.afAuth.auth.currentUser;
if (user) {
return new Promise((resolve, reject) => {
this.afs.collection("pets").doc(user.uid).set({
OwnerName: ownerName,
Petname: PetName,
PetType: type,
PetBreed: breed,
PetSize: size
})
.then((response) => {
resolve(response)
})
.catch((error) => {
reject(error)
});
})
} else {
alert('user not logged in')
}
}
最佳答案
当前您希望将用户的宠物存储在 /pets/userId
中。要在此位置添加每只宠物,您需要使用子集合,因为文档不能容纳其他文档。以下代码添加了一个宠物,该宠物将存储在 /pets/userId/pets/somePetId
中。
addPet(ownerName, petName, type, breed, size){
let user = this.afAuth.auth.currentUser;
if (!user) {
return Promise.reject({code: 'unauthenticated', message: 'user not logged in'})
}
return this.afs.collection("pets").doc(user.uid).collection("pets").add({
OwnerName: ownerName,
OwnerID: user.uid,
PetName: petName,
PetType: type,
PetBreed: breed,
PetSize: size
});
}
但是,您还有另外两种方法可以对此数据进行建模。
全局宠物收藏
不是将宠物保存在 userId
下,而是每只宠物都有自己的 ID,并且您可以将该宠物链接到其主人的 ID。
addPet(ownerName, petName, type, breed, size){
let user = this.afAuth.auth.currentUser;
if (!user) {
return Promise.reject({code: 'unauthenticated', message: 'user not logged in'})
}
return this.afs.collection("pets").add({
OwnerName: ownerName,
OwnerID: user.uid,
PetName: petName,
PetType: type,
PetBreed: breed,
PetSize: size
});
}
要获取给定用户的宠物数组,您可以使用以下命令:
function getPetsForCurrentUser() {
let user = this.afAuth.auth.currentUser;
if (!user) {
return Promise.reject({code: 'unauthenticated', message: 'user not logged in'})
}
return this.afs.collection("pets").where("OwnerID", '==', user.uid).get()
.then(childrenAsArrayOfObjects)
}
用户的宠物子集合
由于您使用的是 Cloud Firestore 而不是实时数据库,因此您可以将每只宠物保存为所有者用户数据的子集合。与实时数据库不同,当您获取 /users/userId
的数据时,您只能获取该特定文档的数据,而不是嵌套在该路径下的所有数据。下面的代码为每只宠物分配自己的 ID,并将其保存到其所有者的子集合中:
addPet(ownerName, petName, type, breed, size){
let user = this.afAuth.auth.currentUser;
if (!user) {
return Promise.reject({code: 'unauthenticated', message: 'user not logged in'})
}
return this.afs.collection("users").doc(user.uid).collection("pets").add({
OwnerName: ownerName,
OwnerID: user.uid,
PetName: petName,
PetType: type,
PetBreed: breed,
PetSize: size
});
}
要获取给定用户的宠物数组,您可以使用以下命令:
function getPetsForCurrentUser() {
let user = this.afAuth.auth.currentUser;
if (!user) {
return Promise.reject({code: 'unauthenticated', message: 'user not logged in'})
}
return this.afs.collection("users").doc(user.uid).collection("pets").get()
.then(childrenAsArrayOfObjects)
}
使用这个数据结构,如果您想查询所有宠物,无论它们的主人是谁,您都可以使用 collection group query .
let ragdollCatsQuery = db.collectionGroup('pets').where('PetType', '==', 'Cat').where('PetBreed', '==', 'Ragdoll');
ragdollCatsQuery.get()
.then(querySnapshot => {
console.log("Found " + querySnapshot.size + " cats with the breed: Ragdoll");
})
其他说明
请使用一致的大小写样式,以防止错误和拼写错误。例如将 Petname
更改为 PetName
以匹配数据库键 OwnerName
的 TitleCase。同样,变量名称的约定是使用驼峰式命名法,因此变量 PetName
应为 petName
。
以上函数均使用以下转换函数:
function childrenAsArrayOfObjects(querySnapshot, idFieldName) {
let idFieldName = (idFieldName && idFieldName + "") || "id";
let children = [];
querySnapshot.forEach(childDoc => {
children.push({...childDoc.data(), [idFieldName]: childDoc.id})
}
return children;
}
如果您想在使用此转换时对文档 ID 使用不同的字段名称,您可以使用:
.then(querySnapshot => childrenAsArrayOfObjects(querySnapshot, "PetID"))
您可以找到其他转换here .
关于javascript - Firestore 嵌套文档在集合文档中具有随机 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59546879/