-4

I have structure for database in this manner

-... location
    -... messages
        -... id1_id2
        -... id3_id4
        -... id5_id6
        .
        .
        .

How can I access a object in messages where I just know id1 which is the key.

TIA.

Peter Haddad
  • 78,874
  • 25
  • 140
  • 134

3 Answers3

2

Change your database to this:

Messages
   userid1
     userid2
        message: hello

then to retrieve message, do this:

DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Messages").child(userid1);
ref.addListenerForSingleValueEvent(new ValueEventListener(){
  @Override
public void onDataChange(DataSnapshot dataSnapshot){
  for (DataSnapshot ds : dataSnapshot.getChildren()) {
    String messages=ds.child("message").getValue().toString();


    }
  }
});
Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
  • I can not change the schema here Peter. and there is no way I can get the messages sent by `id2` –  Apr 16 '18 at 10:36
  • If you do not want to change the scheme then only having id1 will not work. If you have could have both ids then you can do `orderByChild("id1_id2").equalTo(the_ids)`. But anyway what do you want to retrieve then? – Peter Haddad Apr 16 '18 at 10:53
  • I planned to retrieve the chat array which is inside this object. Anyways, thanks a ton for your help. As you said, only `id1` will not work, but again there is no other way to do it but to get the whole database and filter it accordingly. –  Apr 16 '18 at 11:25
  • It is better not to use arrays but, yes that is the only way in this case – Peter Haddad Apr 16 '18 at 11:27
  • Your answer is helpful. but I can't mark it as correct as I still need convincing answer for my question. –  Apr 16 '18 at 17:02
0

Try this one

DatabaseReference ref = FirebaseDatabase.getInstance().getReference("location/messages");
ref.addListenerForSingleValueEvent(new ValueEventListener(){

@Override
public void onDataChange(DataSnapshot dataSnapshot){
   for (DataSnapshot ds : dataSnapshot.getChildren()) {
     if(ds.getKey().contains("bob")){
           //Do something with the date
           break;
       }
     }
   }
});
Android_K.Doe
  • 753
  • 1
  • 4
  • 11
  • This is what I am doing locally, but this needs to be done directly on the database using the Query as there is a lot of unnecessary data which uses my firebase database bandwidth. –  Apr 16 '18 at 09:15
0

Suppose your structure is like this:

enter image description here

You can do something like this, this will grab all nodes from messages that start with id1:

String id1 = "id1";
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference("messages");
        ref.orderByKey().startAt(id1).endAt(id1 + "\uf8ff").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot snap : dataSnapshot.getChildren()) {
                    Log.d("SNAP", snap.getValue(String.class));
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

I took the idea from the javascript implementation, but it also worked in Android, I've run a test on my device/database. Note that this method will work to grab data that starts with the given id.

EDIT:

The idea of querying firebase data that contains a certain string is discussed in this official post. Also, this question as well. The bottom line is that the api doesn't support these types of queries, the approach I mentioned above is the closest you can get of implementing a "SQL LIKE" in firebase. Currently, there's no way of searching for strings that END with another string. The endAt doesn't mean the string ends with id1, but rather that the range of values I want to retrieve finishes at (id1 + "\uf8ff"), that means any string starting with id1. Your options are either change the schema or grab all messages and search locally (the suggestions of the other two answers).

Levi Moreira
  • 11,917
  • 4
  • 32
  • 46