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
}
}
}
Related
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?
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")
I am new to Android and Firebase.. I have stored data in Firebase DB by importing JSON file. Now I am trying to retrieve data in Android textbook. But I am unable to stringify the JSON data, which I did in JavaScript. Also I am not able to get the data in the numerical order, which I am getting in JavaScript.
Following the code DB structure:
// Initialize with secondary app.
FirebaseApp.initializeApp(this /* Context */, SITEINFO, "secondary_SITEINFO");
// Retrieve secondary app.
FirebaseApp secondary_siteinfo = FirebaseApp.getInstance("secondary_SITEINFO");
// Get the database for the other app.
FirebaseDatabase secondaryDB_siteinfo = FirebaseDatabase.getInstance(secondary_siteinfo);
final Query query1 = secondaryDB_siteinfo.getReference("");
fetch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
query1.orderByChild("01-SITEID").equalTo("EKM01").addListenerForSingleValueEvent
(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String Value1 = dataSnapshot.getValue().toString();
My Javascript code
var ref = firebase.database().ref('/').orderByChild("01-SITEID").equalTo(input_final)
ref.on("child_added", function(snapshot) {
var obj = JSON.stringify(snapshot.val());
The Firebase native SDKs for Android and iOS return native types for their respective language. They don't return JSON, nor do they have built-in options to convert the data they return to JSON.
If you need to convert the Java objects to JSON for your app, you will have to implement it yourself (or find a library).
Update
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
To process the result of your query (in the correct order), use DataSnapshot.getChildren():
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: DataSnapshot.getChildren()) {
System.out.println(childSnapshot.getKey()+": "+childSnapshot.child("01-SITEID").getValue());
}
}
I'm using the Android SDK to write device tokens to my Firebase database. I am associating these tokens to users. I am assuming that each user may have one or more devices. Hence, this is what my current database structure looks like:
{
"users" : {
"1" : {
"-LAwu8VKATAxifCOZIPn" : "Device_Token_For_User_1",
"-LAwyfXcoLcXBX3rOshb" : "Device_Token_For_User_1"
},
"8" : {
"-LAwuR9cel-p0kXv-LCn" : "Device_Token_For_User_8"
}
}
}
As you can see, User 1 (represented by the key "1") contains the same token that was written twice but with different keys (left side). These keys are generated randomly because of the push() method. I actually only care about the values themselves, but I want to avoid writing the same token to a particular user more than once.
I push the tokens into my database into the Firebase database this way:
String token = FirebaseInstanceId.getInstance().getToken();
Person currentUser;
try {
currentUser = Reservoir.get("current_user", Person.class);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference();
myRef.child("users").child(Integer.toString(currentUser.id)).push().setValue(token);
} catch (IOException e) {
Log.e("ERROR", "Cannot fetch user from reservoir.");
Toast.makeText(getApplicationContext(), "An unexpected error occurred.", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
All is well, except that when a user logs out and logs in back to the same device, the same token will be pushed twice to the database, which is what happened to User 1.
Instead of using the token as the value you could use it as the key, to ensure it will be unique, and give it an arbitrary value like true.
You would have to change your code like this:
myRef.child("users").child(Integer.toString(currentUser.id)).child(token).setValue(true);
This will result in the following database:
{
"users" : {
"1" : {
"Device_Token_For_User_1" : true,
"SecondDevice_Token_For_User_1" : true
},
"8" : {
"Device_Token_For_User_8" : true
}
}
}
It is better to use the userido, then you can check if the token exists in the database, if it does not exist then you you can add it to the database.
String token = FirebaseInstanceId.getInstance().getToken();
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference();
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
myRef.orderByChild(user.getUid()).equalTo(token).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists()){
myRef.child("users").child(user.getUid()).setValue(token);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
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