gpt4 book ai didi

android - 如何检查firestore中是否已存在某些数据

转载 作者:行者123 更新时间:2023-12-01 16:29:48 25 4
gpt4 key购买 nike

在将新数据添加到 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;
}
}

最佳答案

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

如果您运行此代码,它将打印:

Starting listener

Returning

Got data from 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 的可重用性降低,因为现在它也包含插入新项目的代码。您可以通过定义自己的回调接口(interface)来解决这个问题:

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 实时数据库,其中应用相同的逻辑):

关于android - 如何检查firestore中是否已存在某些数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62073216/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com