如何检查某个数据是不是已存在于firestore中
Posted
技术标签:
【中文标题】如何检查某个数据是不是已存在于firestore中【英文标题】:How to check a certain data already exists in firestore or not如何检查某个数据是否已存在于firestore中 【发布时间】:2018-12-02 15:41:10 【问题描述】:在将新数据添加到 Firestore 之前,我想检查数据库中是否存在相同类型的数据。如果已经存在数据意味着我想防止用户在数据库中输入重复数据. 在我的情况下,如果已经存在同一时间的预订,这就像预约,我想防止用户同时预订。我尝试使用查询功能,但它不能防止重复数据输入。有人请帮助我
private boolean alreadyBooked(final String boname, final String bodept, final String botime)
final int[] flag = 0;
CollectionReference cref=db.collection("bookingdetails");
Query q1=cref.whereEqualTo("time",botime).whereEqualTo("dept",bodept);
q1.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>()
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots)
for (DocumentSnapshot ds : queryDocumentSnapshots)
String rname, rdept, rtime;
rname = ds.getString("name");
rdept = ds.getString("dept");
rtime = ds.getString("time");
if (rdept.equals(botime))
if (rtime.equals(botime))
flag[0] = 1;
return;
);
if(flag[0]==1)
return true;
else
return false;
【问题讨论】:
现在您已经添加了代码 sn-p,我可以看到您正在比较rdept
和 botime
。应该是rdept.equals(bodept)
。
是的,我改变了它,但它仍然无法正常工作。它将所有数据插入数据库而不检查条件@whenthemorningcomes
【参考方案1】:
从 Cloud Firestore 加载数据是异步进行的。当你从alreadyBooked
返回时,数据还没有加载,onSuccess
还没有运行,flag
仍然是默认值。
查看这一点的最简单方法是使用一些日志语句:
private boolean alreadyBooked(final String boname, final String bodept, final String botime)
CollectionReference cref=db.collection("bookingdetails");
Query q1=cref.whereEqualTo("time",botime).whereEqualTo("dept",bodept);
System.out.println("Starting listener");
q1.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>()
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots)
System.out.println("Got data from Firestore");
);
System.out.println("Returning");
如果您运行此代码,它将打印:
开始监听
返回
从 Firestore 获取数据
这可能不是您期望的顺序。但它完美地解释了为什么在调用 alreadyBooked
时总是得到 false
:数据根本没有及时从 Firestore 中返回。
解决这个问题的方法是改变您对问题的看法。您当前的代码具有逻辑:“首先检查它是否已经预订,然后添加一个新项目”。我们需要将其重新定义为:“开始检查它是否已被预订。一旦我们知道不是,添加一个新项目。”在代码中,这意味着所有需要 Firestore 数据的代码都必须在 onSuccess
内,或者必须从那里调用。
最简单的版本是将代码移入 onSuccess
:
private void alreadyBooked(final String boname, final String bodept, final String botime)
CollectionReference cref=db.collection("bookingdetails");
Query q1=cref.whereEqualTo("time",botime).whereEqualTo("dept",bodept);
q1.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>()
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots)
boolean isExisting = false
for (DocumentSnapshot ds : queryDocumentSnapshots)
String rname, rdept, rtime;
rname = ds.getString("name");
rdept = ds.getString("dept");
rtime = ds.getString("time");
if (rdept.equals(botime))
if (rtime.equals(botime))
isExisting = true;
if (!isExisting)
// TODO: add item to Firestore
);
虽然这很简单,但它使alreadyBooked
的可重用性降低,因为现在它也包含插入新项目的代码。你可以通过定义自己的回调接口来解决这个问题:
public interface AlreadyBookedCallback
void onCallback(boolean isAlreadyBooked);
private void alreadyBooked(final String boname, final String bodept, final String botime, AlreadyBookedCallback callback)
CollectionReference cref=db.collection("bookingdetails");
Query q1=cref.whereEqualTo("time",botime).whereEqualTo("dept",bodept);
q1.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>()
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots)
for (DocumentSnapshot ds : queryDocumentSnapshots)
String rname, rdept, rtime;
rname = ds.getString("name");
rdept = ds.getString("dept");
rtime = ds.getString("time");
if (rdept.equals(botime))
if (rtime.equals(botime))
isExisting = true;
callback.onCallback(isExisting)
);
然后你称它为:
alreadyBooked(boname, bodept, botime, new AlreadyBookedCallback()
@Override
public void onCallback(boolean isAlreadyBooked)
// TODO: insert item
);
另请参阅(其中许多适用于 Firebase 实时数据库,适用相同的逻辑):
getContactsFromFirebase() method return an empty list Doug's blog post on asynchronous callbacks Setting Singleton property value in Firebase Listener android + Firebase: synchronous for into an asynchronous function Is it possible to synchronously load data from Firebase? Querying data from firebase【讨论】:
非常感谢您的精彩解释。您提供了解决方案,也让我意识到我的代码有什么问题。非常感谢...以上是关于如何检查某个数据是不是已存在于firestore中的主要内容,如果未能解决你的问题,请参考以下文章
检查 Flutter Firestore 中是不是已存在字段
Swift 5 Firestore:检查数据库中是不是存在集合
使用 React Hooks 和 Context 检查电子邮件是不是已经存在于 Firestore 的集合中