0

I'm developing a reservation mobile app wherein when I click the checkAvailability, it will check if the data already exists in the database. My problem is that I don't know how to access since the key is randomly generated. There is a lot of similar questions to mine but no solutions has been working for me.

Firebase Database(Screenshot):

Database

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

                }
            });

        }
    });
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Reymand
  • 41
  • 1
  • 7
  • refer this https://stackoverflow.com/questions/38948905/how-can-i-check-if-a-value-exists-already-in-a-firebase-data-class-android?answertab=votes#tab-top\ – Infusion Analysts Apr 16 '19 at 13:02
  • Possible duplicate of [How can I check if a value exists already in a Firebase data class Android](https://stackoverflow.com/questions/38948905/how-can-i-check-if-a-value-exists-already-in-a-firebase-data-class-android) – Basi Apr 16 '19 at 13:05
  • You want to check if user have already have `order` under `order->0` ,by using email and key ? – Swati Apr 16 '19 at 13:16
  • Those key like 1554..... is randomly generated and those order are made by all user. I want to know whether the productName and checkIn fields already exists in all keys – Reymand Apr 16 '19 at 13:18

3 Answers3

1

From the looks of it, you're trying to check of there is a child that has order/0 with a specific checkIn and productName under Requests. In your current data structure you can do that with:

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

Differences from your code:

  • I have a loop inside onDataChange, since a query can have multiple results.
  • I hardcoded the date to rule out the problem being caused by the way you input the data in the text view.
  • I handle onCancelled, since ignoring errors is just a bad idea.

A more efficient way to accomplish the same is to have Firebase do part of the query, like this:

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

In here the change is:

  • I moved part of the check into the query, so that Firebase can perform that filter on the server. This means it has to download less data to the client, making it both faster and cheaper.
  • You'll still have to filter the second value client-side, since Firebase queries can only order/filter on one property. For more on this, see Query based on multiple where clauses in Firebase.

Note that you're querying double nested data. While you can get this to work for a specific order (orders/0 in this example), if you can have multiple orders in a request, Firebase won't be able to query across all of them.

For more on this and a solution, see: Firebase Query Double Nested

I'd also recommend reading my answers about modeling categories, because I have a feeling you'll need this soon: Firebase query if child of child contains a value

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference on String type2 = snapshot.child("productName").getValue().toString(); – Reymand Apr 16 '19 at 13:24
  • the only problem I need to solve is how to pass through that 1555413223467 , 1555417771757, and etc. – Reymand Apr 16 '19 at 13:31
0

While storing data you need make user email id as first parameter so that you can access data based on user.

{"reuest":{"xyz@gmail.com":{"orders":[{"checkin":"21:29"},{"checkin":"2:19"}]},"abc@gmail.com":{"orders":[{"checkin":"21:29"},{"checkin":"2:19"}]}}}
rajahsekar
  • 916
  • 1
  • 11
  • 25
0

Finally found a solution on my problem.

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

        }
    });
Reymand
  • 41
  • 1
  • 7