Firebase Android Database - android

I am making an app that should include chat. I would like to display conversations of the current user. I am not sure how to get only chats of the current user. This is my structure of database.
"chats" : {
"-KWYiJiFwE6miPNkKPe0" : {
"chatPartner1" : {
"id" : "rtg3ru7zNYQQp9LA484VIG5rItl1",
"name" : "ghjg",
"photo" : ""
},
"chatPartner2" : {
"id" : "rtg3ru7bzwwewNYQwwewetegb",
"name" : "petra",
"photo" : ""
},
"id" : "-KWYiJiFwE6miPNkKPe0",
"lastMessage" : "dhjcd",
"timestamp" : 1479141836276
}
This json represents storing message for specified chats according to its id.
"messages" : {
"-KWYiJiFwE6miPNkKPe0" : {
"-KWYiJiPWR3n_YcvokCm" : {
"senderId" : "rtg3ru7zNYQQp9LA484VIG5rItl1",
"text" : "dhjcd",
"timestamp" : 1479141836276
}
}
I would need to check if the chatPartner 1 or 2 contains id of the current user. Or do you know about better way to store chats?
Thanks

Related

Getting filtered list values from all users in my firebase Realtime-Database where the list is a child of user

This is how my firebase real-time database looks like.
{
"users" : {
"PDFZ0QOoTxYbCyruOrbiA2y1n5O2" : {
"email" : "mark#outlook.com",
"name" : "Mark Evans",
"paymentMethods" : {
"-ML5oMsCnXgfBRCh7DdO" : {
"paymentProvider" : "Google Pay",
"phone" : "+915555555555",
"userName" : "Mark Evans"
},
"-ML5oRHklHHIK33NQowD" : {
"paymentProvider" : "BHIM",
"phone" : "+911111111111",
"userName" : "Chris Evans"
}
},
"uid" : "PDFZ0QOoTxYbCyruOrbiA2y1n5O2"
},
"epyBsLU0fYOT8uc0Bo698f5SRcO2" : {
"email" : "axle#gmail.com",
"name" : "Axle Blaze",
"paymentMethods" : {
"-ML5o5Zv_3ZixCIXWBqg" : {
"paymentProvider" : "Google Pay",
"phone" : "+918888888888",
"userName" : "Axle Blaze"
},
"-ML5o9pMNucaacdU0G3P" : {
"paymentProvider" : "BHIM",
"phone" : "+911111111111",
"userName" : "Bunny Blaze"
}
},
"uid" : "epyBsLU0fYOT8uc0Bo698f5SRcO2"
}
}
}
I need to get those payment options where phone number = "+91XXXXXXXXXX" no matter from which user payment option belongs to.
For example: If i need all payment options where phone == +911111111111
Result should be :
"-ML5oRHklHHIK33NQowD" : {
"paymentProvider" : "BHIM",
"phone" : "+911111111111",
"userName" : "Chris Evans"
},
"-ML5o9pMNucaacdU0G3P" : {
"paymentProvider" : "BHIM",
"phone" : "+911111111111",
"userName" : "Bunny Blaze"
}
I have to do this in Android but since querying should be similar for any platform so I need help with how the query should be structured.
Any kind of help is appreciated. Thanks in advance.
Firebase queries work on a flat list. The value you order/filter on must be in a fixed location under each direct child node of users.
In your current structure, you can:
Search across all users for direct properties of that user, such as their email or name.
Search across the payment methods of a specific users.
The query you want is not possible on your current data structure. If you want to allow a query across all payment methods of all users, you'll need to change (or augment) your data structure to (also) have a flat list of payment methods across all users.
Also see:
Firebase Query Double Nested
Firebase query if child of child contains a value

In Firebase database, how to keep data consistency when both push and update operations are needed?

Say I have the following database in Firebase, when a user send a new message to another user, it need to push a new message to "ChatThreads/hash(User1,User2)" and update both "UserChats/User1/User2" and "UserChats/User2/User1".
"ChatThreads" : {
"hash(User1,User2)" : {
"1" : {
"message" : "Hello",
"sender" : "User2",
"time" : 9835592
},
"2" : {
"message" : "hi",
"sender" : "User1",
"time" : 10000000
},
"3" : {
"message" : "I am boss",
"sender" : "User2",
"time" : 14835592
}
}
}
},
"UserChats" : {
"User1" : {
"User2" : {
"lastTime" : 14835592,
"latestMessage" : "I am boss"
}
},
"User2" : {
"User1" : {
"lastTime" : 14835592,
"latestMessage" : "I am boss"
}
}
}
How do I keep data consistency in the case?
In the document of Firebase, the method of creating a reference to multiple update's common parent and put all updates in a map was introduced. However, in this case, not only update but also push is needed.
When you call push() without any arguments, you get a unique key that's always generated on the client. (Push ids are always generated locally.) With that key, you can then construct the path to the location where you want to add the data you along with all the other data for that update.

Query to retrieve specific data from Firebase

I am creating an android app and I am stuck at a problem. In order to explain the problem, I would like to show my database structure
{
"EXlzg1COUbOhQjwPCGbS1NRdp5H3" : {
"Contacts" : {
"Contact1" : value (Contact number)
"Contact2" : value
"Contact3" : value
},
"name" : "Sagar Khan",
"phone" : 7276273667
},
"OLm7VWsMcGQpterECyhJ8YTSPna2" : {
"Contacts" : {
"Contact1" : value
"Contact2" : value
"Contact3" : value
},
"name" : "Sameer",
"phone" : 8412914728
},
"TXanCkqtB5PdEogtv8Dzw8y1ngw1" : {
""Contacts" : {
"Contact1" : value
"Contact2" : value
"Contact3" : value
},
"name" : "Harish",
"phone" : 7020743544
},
"qnDVoc72nXa8XvOH1L39VvqFzKL2" : {
"Contacts" : {
"Contact1" : value
"Contact2" : value
"Contact3" : value
},
"name" : "Harish Shinde"
"phone": 8149870822
}
}
This is very short structure the actual one is to big
Now what I want to do is I want to fetch only those users whose contact number is present in current user node and display those users in a Android list.
For example:
User 1 with id EXlzg1COUbOhQjwPCGbS1NRdp5H3 is having 3 contacts
"EXlzg1COUbOhQjwPCGbS1NRdp5H3" : {
"Contacts" : {
"Sameer" : 8412914728 (Contact number)
"Contact2" : value
"Contact3" : value
},
"name" : "Sagar Khan",
"phone" : 7276273667
},
Now when I will fetch the list of users from my database and show it in my Android app list, I want only those users to be added whose contact number is present in User 1 contacts.
My problem is that I literally don't know how to do this as I am new to Android development and Firebase. I am clear with the read and write basics of Firebase, but such operations, I have no idea how to do it.
I have searched a lot, but cannot find any solutions or examples. A detailed description will be very good for me. ;) Thanks in advance.
Here's the change I propose:
This is the new database structure for Users node:
"Users" : {
"EXlzg1COUbOhQjwPCGbS1NRdp5H3" : {
"name" : "Sagar Khan",
"phone" : 7276273667
},
..
}
And the contacts of the user "Sagar Khan" will be stored in another node called Contacts under that user's UserID (EXlzg1COUbOhQjwPCGbS1NRdp5H3) :
"Contacts" : {
"EXlzg1COUbOhQjwPCGbS1NRdp5H3" : {
"Contact1":{
"name" : "Sameer",
"phone" : 7276273000
},
"Contact2":{
"name" : "Alice",
"phone" : 7276273600
},
...
},
//other user id with their contacts
...
}
I suspect that the user ID (eg: EXlzg1COUbOhQjwPCGbS1NRdp5H3) is taken from a logged in user, using:
mAuth.getCurrentUser().getUid();
Therefore, to get the contacts of a logged in user you can query the database like this:
DatabaseReference mUserContactsRef = FirebaseDatabase.getInstance().getReference().child("Contacts").child(mAuth.getCurrentUser().getUid(););
mUserContactsRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot userContact : dataSnapshot.getChildren()){
Contact contact = userContact.getValue(Contact.class);
//add each contact to an arraylist and use it to populate a list of contacts
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You can add each contact object to an ArrayList and use it to populate a list. The key is the User ID, you can access anything related to a user using the UserID.
This is the approach I recommend and what I have used in the past successfully for similar scenarios.

Firebase whitelist and recyclerView

{
"Events" : {
"events" : {
"-KT5UMQAhDHs1bB8bKLc" : {
"activity" : "biking",
"address" : "54°05'45.8\"N 28°19'02.9\"E, просп. Мира 9, Жодино, Беларусь",
"category" : "sport",
"creatorID" : "m11EvlP19OSbEz8XYl2MsNCwGXX2",
"date" : 1475431200689,
"forFriends" : true,
"info" : "вттчтвт",
"name" : "ьаьатвтвтт",
"uid" : "-KT5UMQAhDHs1bB8bKLc"
},
"-KUSsl7RaL-dVoDCoSYT" : {
"activity" : "picnic",
"address" : "Узденский район, Узденский район, Беларусь",
"category" : "entertainment",
"creatorID" : "1RXDSJzSEXakxvNdM41Ae3nbHN72",
"date" : 1477328400000,
"forFriends" : false,
"info" : "45",
"name" : "Test of date",
"uid" : "-KUSsl7RaL-dVoDCoSYT"
}
},
"FriendsOF" : {
"NuKweeGv8zTgt1Vi9RcU3i1u86U2" : {
"1RXDSJzSEXakxvNdM41Ae3nbHN72" : true
},
"m11EvlP19OSbEz8XYl2MsNCwGXX2" : {
"1RXDSJzSEXakxvNdM41Ae3nbHN72" : true
}
},
"Users" : {
"1RXDSJzSEXakxvNdM41Ae3nbHN72" : {
"email" : "*#gmail.com",
"name" : "Алексей Гвоздицкий",
"picture" : "*.jpg"
},
"NuKweeGv8zTgt1Vi9RcU3i1u86U2" : {
"email" : "*#gmail.com",
"name" : "Ольга Гвоздицкая",
"picture" : "*.jpg"
},
"m11EvlP19OSbEz8XYl2MsNCwGXX2" : {
"email" : "*#gmail.com",
"name" : "Егор Александров",
"picture" : "*.jpg"
}
}
}
I have a list of "events". Every "event" can be "forFiends" only (only if current user is in event creators "FriendsOF" list, then he can see this event. FriendsOF it's a whitelist). All availiable for current user events i want to represent in RecyclerView.
I am stucked. I can get all data snapshot and then filter on client side it. But it is not way of Jedi, because i load tonns of unnecessary data. Another solution is to deny acces to event if user should not see it. But i don't understand how to do it. My ref is mEventsRef = FirebaseDatabase.getInstance().getReference().child("Events").child("events"); And rule i can make for
"events":{
"$eventId":{".read":....}
}
So according to this guide i'll get empty recyclerView because of "error callback triggered with PERMISSION_DENIED"
Help me to solve my problem please!

Firebase Retrieve Limited Messages by Auto assigned timestamp

I wish to retrieve only the top 50 messages a user has within the database, with schema:
"individualMessages" : {
"99e4989b-a046-4c5f-9478-5ebd8bdc3ded" : {
"a96da7b1-7c4e-44bc-b82e-fc75bed52bcd" : {
"-KBUjngi9JStE-k4RMUJ" : {
"from" : "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd",
"messageText" : "hey",
"timeSent" : "2016-02-26 17:40:46"
},
"-KBYhsRONfGxVI7Ysb3F" : {
"from" : "a96da7b1-7c4e-44bc-b82e-fc75bed52bcd",
"messageText" : "pool",
"timeSent" : "2016-02-27 12:10:52"
}
},
"fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de" : {
"-KBcYtQ5gD-drFZqz_MU" : {
"from" : "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de",
"messageText" : "ouu",
"timeSent" : "2016-02-28 10:46:52"
},
"-KBcYw24M-9-7H5A3czD" : {
"from" : "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de",
"messageText" : "gsf",
"timeSent" : "2016-02-28 10:47:03"
}
However, simply using:
individualMessageMyPath = myFeastFirebase.child("individualMessages").child(.....
getTop50Messages = individualMessageMyPath.limitToLast(5);
getTop50Messages.orderByChild("timeSent").addChildEventListener(mainMessagingListener);
Returns all messages on that node.
Reviewing the documentation this should work, however it does not.
What is missing?

Categories

Resources