Android 如何检查数据库中是否已经存在数据?

Android 如何检查数据库中是否已经存在数据?,android,firebase-realtime-database,Android,Firebase Realtime Database,我正在开发一个预订移动应用程序,当我点击checkAvailability时,它会检查数据库中是否已经存在数据。我的问题是,我不知道如何访问,因为密钥是随机生成的。我有很多类似的问题,但没有解决办法 Firebase数据库(屏幕截图): btnavaailability.setOnClickListener btnAvailability.setOnClickListener(new View.OnClickListener() { @Override publ

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

Firebase数据库(屏幕截图):

btnavaailability.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) {

                }
            });

        }
    });

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

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

从外观上看,您正在尝试检查是否有一个子项具有
订单/0
,并在
请求下具有特定的
签入
productName
。在您当前的数据结构中,您可以通过以下方式实现:

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查询只能对一个属性进行排序/筛选。有关这方面的更多信息,请参阅

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

有关此问题和解决方案的详细信息,请参阅:


我还建议您阅读我关于建模类别的回答,因为我感觉您很快就会需要它:

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

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

        }
    });

请参阅此\n可能的副本,您想使用电子邮件和密钥检查用户是否已经在
订单->0
下拥有
订单
,这些密钥如1554。。。。。是随机生成的,这些订单由所有用户完成。我想知道productName和checkIn字段是否已存在于所有密钥中。您不能将电子邮件格式作为参数。Firebase不接受itjava.lang.NullPointerException:尝试在字符串type2=snapshot.child(“productName”).getValue().toString()上的空对象引用上调用虚拟方法“java.lang.String java.lang.Object.toString()”;我需要解决的唯一问题是如何通过1555413223467、1555417771757等。