【问题标题】:How can I check If the data already exists in the database?如何检查数据库中是否已存在数据?
【发布时间】:2019-04-17 08:57:18
【问题描述】:

我正在开发一个预订移动应用程序,当我单击 checkAvailability 时,它将检查数据库中是否已经存在数据。我的问题是我不知道如何访问,因为密钥是随机生成的。我有很多类似的问题,但没有任何解决方案对我有用。

Firebase 数据库(屏幕截图):

btnAvailability.setOnClickListener

btnAvailability.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Query userQuery = database.getInstance().getReference().child("Requests")
                    .orderByChild("order/0");
            userQuery.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    String type = dataSnapshot.child("checkIn").getValue().toString();
                    String type2 = dataSnapshot.child("productName").getValue().toString();
                    if(type.equals(checkInTV.getText().toString()) && type2.equals(beach_name.getText().toString())) {
                        Toast.makeText(details.this, "Not Available", Toast.LENGTH_SHORT).show();
                    }else
                    {
                        Toast.makeText(details.this, "Available", Toast.LENGTH_SHORT).show();
                    }

                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });

        }
    });

【问题讨论】:

标签: android firebase-realtime-database


【解决方案1】:

从外观上看,您正在尝试检查是否有一个具有order/0 的孩子,在Requests 下有一个特定的checkInproductName。在您当前的数据结构中,您可以这样做:

Query userQuery = database.getInstance().getReference().child("Requests")
        .orderByChild("order/0");
userQuery.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
            String type = snapshot.child("checkIn").getValue().toString();
            String type2 = snapshot.child("productName").getValue().toString();
            if(type.equals("Saturday, April 20, 2019") && type2.equals("The Mansion")) {
                Toast.makeText(details.this, "Not Available", Toast.LENGTH_SHORT).show();
            }
            else {
                Toast.makeText(details.this, "Available", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException()
    }
});

与您的代码的不同之处:

  • 我在onDataChange 中有一个循环,因为一个查询可以有多个结果。
  • 我对日期进行了硬编码,以排除由您在文本视图中输入数据的方式引起的问题。
  • 我处理onCancelled,因为忽略错误是个坏主意。

更有效的方法是让 Firebase 执行部分查询,如下所示:

Query userQuery = database.getInstance().getReference().child("Requests")
        .orderByChild("order/0/checkIn").equalTo("Saturday, April 20, 2019");
userQuery.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
            String type2 = snapshot.child("productName").getValue().toString();
            if(type2.equals("The Mansion")) {
                Toast.makeText(details.this, "Not Available", Toast.LENGTH_SHORT).show();
            }
            else {
                Toast.makeText(details.this, "Available", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException()
    }
});

这里的变化是:

  • 我将部分检查移到查询中,以便 Firebase 可以在服务器上执行该过滤器。这意味着它必须向客户端下载更少的数据,从而使其更快、更便宜。
  • 您仍然需要在客户端过滤第二个值,因为 Firebase 查询只能对一个属性进行排序/过滤。有关更多信息,请参阅Query based on multiple where clauses in Firebase

请注意,您正在查询双嵌套数据。虽然您可以让它适用于特定订单(在此示例中为 orders/0),但如果您可以在一个请求中包含多个订单,Firebase 将无法查询所有订单。

有关此问题和解决方案的更多信息,请参阅:Firebase Query Double Nested

我还建议阅读我关于建模类别的答案,因为我觉得你很快就会需要这个:Firebase query if child of child contains a value

【讨论】:

  • java.lang.NullPointerException:尝试在 String type2 = snapshot.child("productName) 上的空对象引用上调用虚拟方法 'java.lang.String java.lang.Object.toString()' ").getValue().toString();
  • 我需要解决的唯一问题是如何通过 1555413223467 、 1555417771757 等。
【解决方案2】:

在存储数据时,您需要将用户电子邮件 ID 作为第一个参数,以便您可以根据用户访问数据。

{"reuest":{"xyz@gmail.com":{"orders":[{"checkin":"21:29"},{"checkin":"2:19"}]},"abc@gmail.com":{"orders":[{"checkin":"21:29"},{"checkin":"2:19"}]}}}

【讨论】:

  • 您不能将电子邮件格式作为参数。 Firebase 不接受它
【解决方案3】:

终于找到解决我问题的办法了。

        btnAvailability.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Query userQuery = database.getInstance().getReference().child("Requests")
                    .orderByChild("order/0/checkIn").equalTo(checkInTV.getText().toString());
            userQuery.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
                        String type2 = snapshot.child("order/0/productName").getValue().toString();
                        if(type2.equals(beach_name.getText().toString())) {
                            Toast.makeText(details.this, "Not Available", Toast.LENGTH_SHORT).show();
                        }
                        else {
                            Toast.makeText(details.this, "Available", Toast.LENGTH_SHORT).show();
                        }
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    throw databaseError.toException();
                }
            });

        }
    });

【讨论】:

    猜你喜欢
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    相关资源
    最近更新 更多