给定给定的 Firestore 路径,检查该记录是否存在或不缺少创建可观察的文档并订阅它的最简单、最优雅的方法是什么?
看看这个问题,看起来
.exists
仍然可以像标准Firebase数据库一样使用。此外,您还可以在 github 上找到更多讨论此问题的人here
文档指出
新示例
var docRef = db.collection("cities").doc("SF");
docRef.get().then((doc) => {
if (doc.exists) {
console.log("Document data:", doc.data());
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch((error) => {
console.log("Error getting document:", error);
});
老例子
const cityRef = db.collection('cities').doc('SF');
const doc = await cityRef.get();
if (!doc.exists) {
console.log('No such document!');
} else {
console.log('Document data:', doc.data());
}
注意:如果 docRef 引用的位置没有文档,则生成的文档将为空,并且调用它会返回 false。
老例子2
var cityRef = db.collection('cities').doc('SF');
var getDoc = cityRef.get()
.then(doc => {
if (!doc.exists) {
console.log('No such document!');
} else {
console.log('Document data:', doc.data());
}
})
.catch(err => {
console.log('Error getting document', err);
});
如果模型包含太多字段,最好在
CollectionReference::get()
结果上应用字段掩码(让我们保存更多谷歌云流量计划,\o/)。因此,选择使用 CollectionReference::select()
+ CollectionReference::where()
来仅选择我们想要从 firestore 获取的内容是一个好主意。
假设我们有与 firestore cities example 相同的集合模式,但文档中的
id
字段具有与 doc::id
相同的值。然后你可以这样做:
var docRef = db.collection("cities").select("id").where("id", "==", "SF");
docRef.get().then(function(doc) {
if (!doc.empty) {
console.log("Document data:", doc[0].data());
} else {
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
现在我们只下载
city::id
,而不是下载整个文档来检查它是否存在。
检查这个:)
var doc = firestore.collection('some_collection').doc('some_doc');
doc.get().then((docData) => {
if (docData.exists) {
// document exists (online/offline)
} else {
// document does not exist (only on online)
}
}).catch((fail) => {
// Either
// 1. failed to read due to some reason such as permission denied ( online )
// 2. failed because document does not exists on local storage ( offline )
});
count()
聚合 来检查文档是否存在而无需下载它。
这是一个 TypeScript 示例:
import { getCountFromServer, query, collection, documentId } from '@firebase/firestore'
const db = // ...
async function userExists(id: string): Promise<boolean> {
const snap = await getCountFromServer(query(
collection(db, 'users'), where(documentId(), '==', id)
))
return !!snap.data().count
}
我最近在使用 Firebase Firestore 时遇到了同样的问题,我使用以下方法来克服它。
mDb.collection("Users").document(mAuth.getUid()).collection("tasks").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
if (task.getResult().isEmpty()){
Log.d("Test","Empty Data");
}else{
//Documents Found . add your Business logic here
}
}
}
});
task.getResult().isEmpty() 提供了是否找到符合我们查询的文档的解决方案
根据您使用的库,它可能是可观察的而不是承诺。只有 Promise 才会有“then”语句。您可以使用“doc”方法代替 collection.doc 方法,或 toPromise() 等。以下是 doc 方法的示例:
let userRef = this.afs.firestore.doc(`users/${uid}`)
.get()
.then((doc) => {
if (!doc.exists) {
} else {
}
});
})
希望这有帮助...
如果出于某种原因你想在 Angular 中使用 observable 和 rxjs 而不是 Promise:
this.afs.doc('cities', "SF")
.valueChanges()
.pipe(
take(1),
tap((doc: any) => {
if (doc) {
console.log("exists");
return;
}
console.log("nope")
}));
我认为这可能已经过时了,但想添加我的想法...现在有一个“限制”函数来限制查询,对于“存在”我们只需要 0 或 1。
所以我认为最有效的“存在”是添加针对查询的限制,然后“计数” - 像这样的辅助函数;
private async exists(query: firestore.Query<firestore.DocumentData, firestore.DocumentData>): Promise<boolean> {
const constrainedCount = await query.limit(1).count().get();
return constrainedCount.data().count == 0;
}