How can I orderByChild on Android Firebase chat based application? - android

I'm trying to build a user to user chat application, but I'm not able to order the chat list by last message sent.
My Firebase (real time) structure is like this:
I'm trying to retrieve the data like this, but i'm not able to order by "timestamp" in the inner message.
final String uID = firebaseAuth.getCurrentUser().getUid();
Query ref = FirebaseDatabase.getInstance().getReference("Messages");
ref.orderByChild("timestamp").startAt(uID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Did anyone knows how can I order the list of users by the timestamp of the last message?

You need to change the query to the following:
final String uID = firebaseAuth.getCurrentUser().getUid();
Query ref = FirebaseDatabase.getInstance().getReference("Messages");
ref.child(uID_uID).orderByChild("timestamp").addValueEventListener(new ValueEventListener() {
You need access to the direct node under the node Messages, the node with underscore. Then you can add orderByChild("timestamp").equalTo("157644739279")

Related

how to check the current Firebase data under uid?

I am trying to check uid from firebase Realtime database, but its only returns the current uid and when I try to check uid with previous uid then also it only returns the current uid. I had tried many ways and searched but I can't get the exact solution, please if any one could help.
here what I am using to check the uid
FirebaseAuth.getInstance().getCurrentUser().getUid();
here is my code how I am trying to check
String userEnteredUserName = binding.textLoginUserName.getEditText().getText().toString().trim();
String userEnteredPassword = binding.textPassword.getEditText().getText().toString().trim();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
Query checkUser = reference.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).orderByChild("userName").equalTo(userEnteredUserName);
Log.d("uids", "uid: " + uid);
checkUser.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
binding.textLoginUserName.setError(null);
binding.textLoginUserName.setErrorEnabled(false);
Log.d("users", "Username: " + snapshot.toString());
if (snapshot.exists()) {
String passwordFromDB = snapshot.child(userEnteredUserName).child("password").getValue(String.class);
if (passwordFromDB.equals(userEnteredPassword)) {
//next activity
}else{
Toast.makeText(Login.this, "Error", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(Login.this, "Error", Toast.LENGTH_SHORT).show();
}
});
In log what I get,
2022-02-06 13:13:06.173 18093-18093/abc C/uids: uid: OFtpR6bfISP3Odd9K1oGWCQmeEf2
Here is my firebase data, "aisha12" is working which is under the current uid but when I try to check "vgbb" it returns only the current uid
If I understand correctly, you are trying to allow a user to register a username and ensuring that the username is unique. Your current data structure doesn't allow you to do that query though.
Firebase Realtime Database can only order/filter on a value that is at a fixed path under each child node of the location you query. So in your current code:
reference.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).orderByChild("userName").equalTo(userEnteredUserName);
You are querying the direct child nodes of /Users/$uid looking for the username under there. Since you're specifying the UID in that path, you're only searching under that specific user.
There is no way with your current data structure to search across all /Users, since the property you are looking for is under /Users/$uid/$username/userName, so with two dynamic keys in there, and the database can only handle one dynamic key.
To allow the query, you will need to change the data structure and remove the $userName level from it, so that you get:
Users: {
"3l6Rm....": {
"userName": "vgbb",
...
},
"OftpR...": {
"userName": "aisha12",
...
}
}
Now you can search for the username with:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
Query checkUser = reference.orderByChild("userName").equalTo(userEnteredUserName);
I also recommend checking out these previous questions on allowing a user to register a unique username:
How do you prevent duplicate user properties in Firebase?
Firebase security rules to check unique value of a child #AskFirebase
How to check if usernames are unique in Firebase
unique property in Firebase
How to give unique usernames from a list of usernames to the users in the firebase
Check value already exists or not in Firebase?

android Firebase query- reference to (pushid )?

Please help
this is my firebase structure
firebase structure
following query is working fine but i have to hardcode the push id "MZgPRv6xKK5isnnPTLn" , i dont want to hard code the value highlighted below from following query is there a way to get this reference of this push key ? to be used for query so that i can replace the "MZgPRv6xKK5isnnPTLn"
push id hard coded
Query lastQuery = dbr1.child("users").child(mAuth.getCurrentUser().getUid())
.child("-MZgPRv6xKK5isnnPTLn").child("sms").orderByKey().limitToLast(1);
lastQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dns) {
for (DataSnapshot chl : dns.getChildren())
{
Log.d("read_last_nodes", String.valueOf(dns.child("no").getValue()));
}
}
}
Follows is the code of writing into Firebase
path= dbref_1.child("users").child(mAuth.getUid()).push().getKey();
dbref_1.child("users").child(mAuth.getCurrentUser().getUid()).child(path)
.child("sms").child("SMS_no_" + i).child("no").setValue(no);
You can use 'getKey()' to get any key in firebase database. In your case to get the key you have to point to the hardcoded key, and then use getKey on the returned snapshot. After getting the key you can proceed to run your query.
DatabaseReference ref = dbr1.child("users").child(mAuth.getCurrentUser().getUid())
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dns) {
if(dns.exists) {
String key = dns.getKey();
Query lastQuery = dns.child(key).child("sms").orderByKey().limitToLast(1);
///rest of query logic
}
}
}

Retrieve data from multiple push ids under a single child in firebase realtime database

I am new to android studio and programming and am currently trying to make my first app. In firebase RTDB, I have multiple push ids under a single child that keep on increasing in number as the user presses certain buttons, and they all store only an integer. I want to retrieve the data from all those push ids(or keys, I don't really know what they are actually called) under the child and then sum the integers up and display the result in a textView and do it every time a new field is added. How can I do that? So far I only know how to normally send and receive data to childs sub-childs like this but i have never ever used push ids or keys before:
String recieve = datasnapshot.child("Child").child("subchild").getText().toString();
String send = "send";
databaseReferenc.child("Child").child("sunchile").setValue(send);
The data tree in firebase is as follows:
Assuming that Australia is a direct child of your Firebase Realtime Database root, to sum all those values, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference australiaRef = rootRef.child("Australia");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int total = 0;
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String value = Integer.parseInt(ds.getValue(String.class));
total += value;
}
Log.d("TAG", "total: " + total);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
australiaRef.addListenerForSingleValueEvent(valueEventListener);
One more thing. Because you are storing numbers, it best to store them as long values and not as String values.

Returning zero nodes in realtime startAt query

Im trying to make pagination with Realtime db. I am making query first time with limit 15 and second time based on last item uid i am making second query where suppose to startAt() with that uid. After first query I am receiving as it suppose to 15 items. Next time it suppose to send me back 9 items. But it sends me zero
The code of response
DatabaseReference mReference = realtimeReference.child("OnlineUsers/" + neededGender);
Query query;
if (uid.equals("")){
query = mReference.orderByChild("rating").limitToLast(TOTAL_ITEMS_TO_LOAD);
}else {
//Pagination query with last uid to start
query = mReference.orderByChild("rating").startAt(uid).limitToLast(TOTAL_ITEMS_TO_LOAD);
}
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
final List<OnlineUser> userList = new ArrayList<>();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
OnlineUser user = postSnapshot.getValue(OnlineUser.class);
userList.add(new OnlineUser(user.getUid(), user.getName(), user.getImage(), user.getGender(), user.getCountry(), user.getRating()));
}
EventBus.getDefault().post(new ListEvent(userList));
}
Database structure
When paginating, you always need to pass the value of the property that you order on. In addition, if there are multiple nodes with the same value for that property, you should pass the key of of the first item to return.
So in your case that'd be:
mReference.orderByChild("rating").startAt(rating, key).limitToLast(TOTAL_ITEMS_TO_LOAD);
This assumes that you have the rating of the node in rating and its key in key.

How to search anywhere in string in Firebase Database - Android

I have implemented firebase realtime database in my android app, everything is fine. I am trying to add a a search function and I am able to search the database with only starting word match.
Below is my database snapshot:
I am querying for movieName. Right now I am able to search if the query string is Pets/Pe/pet. But when I search for Animals, I get zero results. So, basically what I am looking for is searching the database with query text anywhere in the string. ie., I should be able to search Animals/and/pets and should get the results which contain the search query.
Below is my code so far.
mDatabaseReference.child("recent").getRef().orderByChild("movieName").startAt(query)
.endAt(query + "\uf8ff")
To seach for a string within a String please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference animalsRef = rootRef.child("Animals");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Boolean found;
String search = "Animals";
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String movieName = ds.child("movieName").getValue(String.class);
found = movieName.contains(search);
Log.d("TAG", movieName + " / " + found);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
animalsRef.addListenerForSingleValueEvent(eventListener);
As you see, we query the database for all the movie names and then search for the desired word within the movieName.
First of all check the exact child and initialize the Firebase as like. Have a look at this answer,
https://stackoverflow.com/a/34537728/5746625

Categories

Resources