如何检查某个数据是否已经存在于firestore中 [英] How to check a certain data already exists in firestore or not

查看:25
本文介绍了如何检查某个数据是否已经存在于firestore中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将新数据添加到 firestore 之前,我想检查数据库中是否存在相同类型的数据.如果已经存在数据意味着我想防止用户在数据库中输入重复数据.在我的情况下,如果已经存在同一时间的预订,它就像一个预约预订,我想防止用户在同一时间预订.我尝试使用查询功能,但它并不能防止重复数据输入.请帮助我

Before adding a new data into the firestore, i want to check already a data of the same kind exists in the database or not.if already a data was present means i want to prevent the user from entering duplicate data in the database. In my case it is like a appointment booking if already a booking for the same time exists,i want to prevent to users to book on the same time.i tried using query function but it is not preventing duplicate data entering.someone plz help me

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 仍具有其默认值价值.

Loading data from Cloud Firestore happens asynchronously. By the time you return from alreadyBooked, the data hasn't loaded yet, onSuccess hasn't run yet, and flag still has its default value.

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

The easiest way to see this is with a few log statements:

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

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

If you run this code it will print:

开始监听

返回

从 Firestore 获取数据

Got data from Firestore

这可能不是您期望的顺序.但这完美地解释了为什么在调用 alreadyBooked 时总是得到 false:数据根本没有及时从 Firestore 返回.

That's probably not the order you expected. But it perfectly explains why you always get false when calling alreadyBooked: the data simply didn't come back from Firestore in time.

对此的解决方案是改变您对问题的看法.您当前的代码具有逻辑:首先检查它是否已被预订,然后添加新项目".我们需要将其重新定义为:开始检查它是​​否已被预订.一旦我们知道这不是,就添加一个新项目."在代码中,这意味着需要来自 Firestore 数据的所有代码都必须在 onSuccess 内,或者必须从那里调用.

The solution for this is to change the way you think about the problem. Your current code has logic: "First check if it is already booked, then add a new item". We need to reframe this as: "Start checking if it is already booked. Once we know that is isn't, add a new item." In code this means that all code that needs data from Firestore must be inside the onSuccess or must be called from there.

最简单的版本是将代码移入 onSuccess:

The simplest version is to move the code into 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 的可重用性,因为现在它也包含插入新项目的代码.你可以通过定义自己的回调接口来解决这个问题:

While this is simple, it makes alreadyBooked less reusable since now it contains the code to insert the new item too. You can solve this by defining your own callback 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 实时数据库,其中适用相同的逻辑):

Also see (many of these are for the Firebase Realtime Database, where the same logic applies):

这篇关于如何检查某个数据是否已经存在于firestore中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆