如果 Firestore 记录的路径已知,检查其是否存在的最佳方法是什么?

问题描述 投票:0回答:8

给定给定的 Firestore 路径,检查该记录是否存在或不缺少创建可观察的文档并订阅它的最简单、最优雅的方法是什么?

firebase angularfire2 google-cloud-firestore
8个回答
58
投票

看看这个问题,看起来

.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);
    });

10
投票

如果模型包含太多字段,最好在

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
,而不是下载整个文档来检查它是否存在。


6
投票

检查这个:)

  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 )
  });

3
投票

2022 年答案:您现在可以使用

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
}

0
投票

我最近在使用 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() 提供了是否找到符合我们查询的文档的解决方案


0
投票

根据您使用的库,它可能是可观察的而不是承诺。只有 Promise 才会有“then”语句。您可以使用“doc”方法代替 collection.doc 方法,或 toPromise() 等。以下是 doc 方法的示例:

let userRef = this.afs.firestore.doc(`users/${uid}`)
.get()
.then((doc) => {
  if (!doc.exists) {

  } else {

  }
});

})

希望这有帮助...


0
投票

如果出于某种原因你想在 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
投票

我认为这可能已经过时了,但想添加我的想法...现在有一个“限制”函数来限制查询,对于“存在”我们只需要 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;
  }
© www.soinside.com 2019 - 2024. All rights reserved.