In my app, I have used Firebase database and stored userID in a child and set the value of the child as username to get the username of the current user. Now I'm using addValueEventListener to get the username from the database. This is my Firebase structure.
The code is given below.
checkUsername.child("check").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
currentUser = dataSnapshot.child(getUserID()).getValue(String.class);
Log.d(TAG, "onDataChange: currentUser = " + currentUser);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
While debugging, String currentUser returns null.
Screenshot of debugged answer.
Since you have added the valueEventListener at the check node, so getting the child again makes no sense (Because the User ID is the key of check node and not a separate child).
Instead try calling dataSnapshot.getChildren(); directly to get the entire list of updated data and iterate through it to get whatever key value you need.
Something like this,
checkUsername.child("check").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
String current value = dataSnapshot.getValue(String.class);
Log.d("TAG", "onDataChange: " + current value);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
Another option in this particular use case is to add a ChildEventListener and get the value inside onChildAdded() method.
How do I search for users based on their usernames? I have looked at numerous SO posts on this matter but am still unable to achieve what I want to do.. I have tried to apply what I saw in those posts and is shown below:
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("users");
usersRef.orderByChild("username")
.startAt(queryText)
.endAt(queryText+"\uf8ff");
usersRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
searchList = new ArrayList<>();
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
User user = postSnapshot.getValue(User.class);
Log.d("USER: ", "" + user.getUsername());
searchList.add(user);
}
adapter = new UserCardAdapter(getContext(), searchList);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("onQueryTextChange: " ,databaseError.getMessage());
}
});
However, all users are still retrieved. I have seen the usage of startAt() and endAt() supposedly work for others on other posts but I cannot manage to get it to work for me..
This is how the user data is stored:
User Data Structure
You almost done right but you should add addListenerForSingleValueEvent after the database reference that already apply orderBy() , startAt(), endAt() like this.
usersRef.orderByChild("username")
.startAt(queryText)
.endAt(queryText+"\uf8ff")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
searchList = new ArrayList<>();
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
User user = postSnapshot.getValue(User.class);
Log.d("USER: ", "" + user.getUsername());
searchList.add(user);
}
adapter = new UserCardAdapter(getContext(), searchList);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("onQueryTextChange: " ,databaseError.getMessage());
}
});
Your use of orderBy(), startAt(), and endAt() is correct according to the documentation.
But the addListener method must be applied directly to the object returned by the chain of orderByChild(), startAt(), and endAt() methods, and not in a new statement on the DatabaseReference retrieved with ... .getReference("users").
If you use a ChildEventListener:
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("users");
usersRef.orderByChild("username")
.startAt(queryText)
.endAt(queryText+"\uf8ff");
.addChildEventListener(new ChildEventListener() {
List<User> searchList = new ArrayList<>();
#Override public void onChildAdded(DataSnapshot dataSnapshot, String s) {
User user = dataSnapshot.getValue(User.class);
Log.d("USER: ", "" + user.getUsername());
searchList.add(user);
}
#Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
#Override public void onChildRemoved(DataSnapshot dataSnapshot) {}
#Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
#Override public void onCancelled(DatabaseError databaseError) {}
});
HI everyone I want to catch all the keys on my firebase database:
Users-
26dfg678-
Name: jack
Job: Farmer
43jkhjh4-
Name: bill
Job: ICT
I want to catch the id: 26dfg678 and 43jkhjh4 and put them in an array. This is my code:
final DatabaseReference database_nomi = firebaseDatabase.getReference().child("Users");
database_nomi.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//here
**name[0] = dataSnapshot.getKey();
Provee.setText(name[0]);**
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
if i do this it takes only the last but i want all..
To do this you need to read through your Firebase snapshot using a ValueEventListener (and addListenerForSingleValueEvent).
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
int i = 0;
for(DataSnapshot d : dataSnapshot.getChildren()) {
name[i] = d.getKey();
i++;
}
}
}//onDataChange
#Override
public void onCancelled(DatabaseError error) {
}//onCancelled
});
This code uses a foreach to read all dataSnapshot children, saving its key in an array at each iteration.
How can I get that value while I know nothing about the push key?
+users
+9JZTuGUzc8bx7FLrwResWmp8L583
+anon:
+email:
+fid: <- i want to get this id without knowing push key (9JZTuGUzc8bx7FLrwResWmp8L583 )
+username:
Currently, I am trying with a null response:
FirebaseDatabase.getInstance().getReference().child("users").orderByChild("anon").equalTo(getIntent().getStringExtra(EXTRA_POST_USERNAME))
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user information
if(dataSnapshot.exists()){
User user = dataSnapshot.getValue(User.class);
fidanon = user.fid;}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
final Query query = FirebaseDatabase.getInstance().getReference().child("users").orderByChild("anon").equalTo(getIntent().getStringExtra(EXTRA_POST_USERNAME));
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot != null) {
final String fid = dataSnapshot.child("fid").getValue().toString();
Toast.makeText(getActivity(), fid, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Use this,will solve your problem.
I want to retrive the id that generated by firebase when I pushed value to it like next
I want to retrieve "-KGdKiPSODz7JXzlgl9J" this id for that email
I tried by getKey() but it return "users"
and when user get value it return the whole object from the id to profile picture and that won't make me get it as User object in my app
how solve this ?
Firebase users = myFirebaseRef.child("users");
users.orderByChild("email").equalTo("z#m.com").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dataSnapshot.getKey();
Log.d("User",dataSnapshot.getRef().toString());
Log.d("User",dataSnapshot.getValue().toString());
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.d("User",firebaseError.getMessage() );
}
});
You can read the key from push() without pushing the values. Later you can create a child with that key and push the values for that key.
// read the index key
String mGroupId = mGroupRef.push().getKey();
....
....
// create a child with index value
mGroupRef.child(mGroupId).setValue(new ChatGroup());
mGroupId contains the key which is used to index the value you're about to save.
UPDATE 1:
it can obtain also by one line
String key = mDatabase.child("posts").push().getKey();
//**************************************************************//
after searching and trying a lot of things i came to 2 ways to do that
.
1. first one to get the key when i upload the post to the server via this function
public void uploadPostToFirebase(Post post) {
DatabaseReference mFirebase = mFirebaseObject
.getReference(Constants.ACTIVE_POSTS_KEY)
.child(post.type);
mFirebase.push().setValue(post);
Log.d("Post Key" , mFirebase.getKey());
}
i used it in my code to get the key after i have already pushed it to node for it in my database
public void getUserKey(String email) {
Query queryRef = databaseRef.child(Constants.USERS_KEY)
.orderByChild(Constants.USERS_EMAIL)
.equalTo(email);
queryRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//TODO auto generated
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
//TODO auto generated;
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
//TODO auto generated;
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
//TODO auto generated
}
#Override
public void onCancelled(DatabaseError databaseError) {
//TODO auto generated
}
});
}
When you fire a Firebase query there can potentially be multiple results. So when you ask for the value of a query, Firebase returns a list of items. Even if there is only one matching item, it will be a list of one item.
So you will have to handle this list in your code:
users.orderByChild("email").equalTo("z#m.com").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child: dataSnapshot.getChildren()) {
Log.d("User key", child.getKey());
Log.d("User ref", child.getRef().toString());
Log.d("User val", child.getValue().toString());
}
}
In Java - Android Studio, you can get the unique pushed ID as the item is written to the db...
Per "Firebase's: Save Data on Android": You can use the reference to the new data returned by the push() method to get the value of the child's auto-generated key or set data for the child. Calling getKey() on a push() reference returns the value of the auto-generated key.
To get the reference at write time, instead of loading DATA with a single push()...
use push() to create a blank record in the database, return value is the record's reference.
use .getKey() to get the Key for that record.
use .setValue(DATA) to fill in the blank record
here's an example:
FirebaseDatabase fb_db_instance = FirebaseDatabase.getInstance();
DatabaseReference db_ref_Main = fb_db_instance.getReference("string_db_Branch_Name");
hashMap_record = new HashMap<String, String>(); //some random data
hashMap_record.put("key_Item1", "string_Item1");
hashMap_record.put("key_Item2", "string_Item2");
DatabaseReference blankRecordReference = db_ref_Main ;
DatabaseReference db_ref = blankRecordReference.push(); //creates blank record in db
String str_NEW_Records_Key = db_ref.getKey(); //the UniqueID/key you seek
db_ref.setValue( hashMap_record); //sets the record
I solved it to get id you need to use firebase url
String uid = firebaseRef.child("users").push().getKey();
Log.i("uid", uid);
this will give you the key KG.....
For those using TVAC Tutorials(https://www.youtube.com/watch?v=cSMMWOHkP68&list=PLGCjwl1RrtcTXrWuRTa59RyRmQ4OedWrt&index=16)
You can get Key using onClick method as follows:
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String key = getRef(position).getKey();
}
});
Just add new field to Users like userID, when you create new User add uid and than you can receive it by reading query
I'm doing it like this.
String userID;// in Users
Firebase users = myFirebaseRef.child("users");
users.orderByChild("email").equalTo("z#m.com").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Users user= dataSnapshot.getChildren().iterator().next().getValue(Users.class);
Log.d("User",user.getUserID());
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.d("User",firebaseError.getMessage() );
}
});
I had faced this problem and I found the solution,
you can get it using this code:
dataSnapshot.getChildren().iterator().next().getKey()
// Unity, code in C#
{
reference = FirebaseDatabase.DefaultInstance.RootReference;
string s = reference.Push().Key;
reference.Child(s).Child(Username).SetValueAsync(Username);
Debug.Log(s);
}
Another Option to get the unique Post-id from firebase is by getting key (dataSnapshot.getKey()) in #Override method public void onChildAdded and maintaining it locally for example
private void attachDatabaseReadListener() {
if (mTaskEventListener == null) {
mTaskEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Task friendlyMessage = dataSnapshot.getValue(Task.class);
friendlyMessage.setId(dataSnapshot.getKey());
System.out.println("friendlyMessage = " + friendlyMessage);
DummyContent.ITEMS.add(new DummyContent.DummyItem("" + DummyContent.ITEMS.size()+1,friendlyMessage.getStatus(),friendlyMessage.getSummary()));
}
public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
public void onChildRemoved(DataSnapshot dataSnapshot) {}
public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
public void onCancelled(DatabaseError databaseError) {}
};
mUserDatabaseReference.addChildEventListener(mTaskEventListener); // remove it
}
}
dataSnapshot.getKey will set the unique post id in Task Instance and can be used later to perform any update operation.
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference databaseReference1 = firebaseDatabase.getReference("users");
databaseReference1.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
String key = dataSnapshot1.getKey();
Log.d(TAG, "onCreate: key :" + key);
String email = dataSnapshot1.child("email").getValue(String.class);
String roomno =dataSnapshot1.child("address").getValue(String.class);
Log.d(TAG, "onDataChange: email: " + email);
Log.d(TAG, "onDataChange: address: " + address)
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Use this
mFirebaseDatabase=mFirebaseDatabase.getInstance().getReference("tablename");
Query query = mFirebaseDatabase.orderByChild("tablenme").getRef();
query.orderByChild("Id").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
String id =dataSnapshot1.child("Id").getKey();
String Name = dataSnapshot1.child("Name").getValue().toString();
String lastName= dataSnapshot1.child("lastname").getValue().toString();
flatDataGets.add(Name+"-"+lastname);
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(RagisterActivity.this, R.layout.support_simple_spinner_dropdown_item, DataGets);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mRegisterSpinner.setAdapter(arrayAdapter);
mRegisterSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
flatName =DataGets.get(position);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Yes, you can retrieve the node or main child name by adding its name in that particular child as a key and value {main_child_name}.
Simply do similar:
HashMap<String, Object> hashLcl = new HashMap<>();
hashLcl.put("admin", firebaseUser.getUid());
hashLcl.put("name", textPrm);
DatabaseReference referenceLcl = FirebaseDatabase.getInstance().getReference();
String keyLcl = referenceLcl.child("GroupChats").push().getKey();
hashLcl.put("key", keyLcl);
Task task = referenceLcl.child("GroupChats").child(keyLcl).setValue(hashLcl);
task.addOnSuccessListener(aVoid -> {
//the data is added and now we are sure to do something related
});
This is the result:
String id = Objects.requireNonNull(task.getResult().getUser()).getUid();