Android 如何检查firestore中是否存在特定数据

Android 如何检查firestore中是否存在特定数据,android,firebase,google-cloud-firestore,Android,Firebase,Google Cloud Firestore,在将新数据添加到firestore之前,我想检查数据库中是否已经存在同类数据。如果已经存在数据,则意味着我想防止用户在数据库中输入重复数据。 在我的情况下,这就像预约一样,如果已经存在同一时间的预约,我想阻止用户在同一时间预订。我尝试使用查询功能,但它不能阻止重复数据输入。请有人帮助我 private boolean alreadyBooked(final String boname, final String bodept, final String botime) { fin

在将新数据添加到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;
        }
    }
private boolean已准备就绪(最终字符串boname、最终字符串bodept、最终字符串botime){
最终int[]标志={0};
CollectionReference cref=db.collection(“预订详情”);
查询q1=cref.whereEqualTo(“time”,botime)。whereEqualTo(“dept”,bodept);
q1.get().addOnSuccessListener(新的OnSuccessListener()){
@凌驾
成功时公共无效(QuerySnapshot QueryDocumentSnapshot){
用于(文档快照ds:queryDocumentSnapshots){
字符串rname、rdept、rtime;
rname=ds.getString(“名称”);
rdept=ds.getString(“dept”);
rtime=ds.getString(“时间”);
如果(rdept.等于(botime)){
if(rtime.equals(botime)){
标志[0]=1;
返回;
}
}
}
}
});
如果(标志[0]==1){
返回true;
}
否则{
返回false;
}
}

从云Firestore加载数据是异步进行的。当您从
alreadyBooked
返回时,数据尚未加载,
onSuccess
尚未运行,
标志仍有其默认值

查看这一点的最简单方法是使用一些日志语句:

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");
}
虽然这很简单,但它使
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)
        }
    });
}
另请参见(其中许多用于Firebase实时数据库,其中同样的逻辑适用):


现在您已经添加了代码片段,我可以看到您正在将
rdept
botime
进行比较。它应该是
rdept.equals(bodept)
。是的,我更改了它,但它仍然不起作用。它将所有数据插入数据库,而不检查条件@whenthemorningcomest。非常感谢您的精彩解释。您给出了一个解决方案,也让我意识到了代码中的错误。非常感谢。。。
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
  }
});