I want to retrieve data for a given user ID, which I am storing as a value in the database under each user. My database structure looks like below:
user: {
UserID: {
uniqueId: {
Name: ""
Email: ""
userId: ""
}
UserID: {
uniqueId: {
Name: ""
Email: ""
userId: ""
}
}
I tried this but it doesn't seem to work as it doesn't display anything on the app:
FirebaseUser user = mAuth.getCurrentUser();
df.child("UsersTable").orderByChild("userid").equalTo(user.getUid())).addChildEventListener
even when I try to give a specific value like below, it still does not read from firebase:
------------- Updated:
I want to get all data from userID. so for example, I want to retrieve all information from fmXWU324VHdDb8v6h7gvNjRojnu33, which will be name, email and userid.
UserTable
{
"fmXWU324VHdDb8v6h7gvNjRojnu33" : {
"-KbJtw467nl6p253HZ537" : {
"Name" : "name1",
"Email" : "something1#something.com",
"userid" : "fmXWU324VHdDb8v6h7gvNjRojnu33"
}
},
"pJtC45fW0MMi352UiPWnWdIS7h88" : {
"-Kb012ls9iMnzEL723o9I" : {
"Name" : "name2",
"Email" : "something2#something.com",
"userid" : "pJtC45fW0MMi352UiPWnWdIS7h88"
},
"-Kb0aq0q25FJq38256SrC" : {
"Name" : "name3",
"Email" : "something3#something.com",
"userid" : "pJtC45fW0MMi352UiPWnWdIS7h88"
},
"-Kb0atopfK64F6jy124Qi1u" : {
"Name" : "name3",
"Email" : "something1#something.com",
"userid" : "pJtC45fW0MMi352UiPWnWdIS7h88"
}
}
Update 2:
DatabaseReference df= FirebaseDatabase.getInstance()
.getReference("user").child(getCurrentUser().getUid());
df.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
get(dataSnapshot);
}
....
...
Update 3:
I assume based on what I am looking for (getting all data under defined userId) the query should look something like this:
df.child("UserTable").child(user.getUid())).addChildEventListener(new ChildEventListener()
However, this is throwing this error:
Can't convert object of type java.lang.String to type com.android.example.UserTable
Try Using addChildEventListener and Query like following..
mReference.child("user").orderByChild("userId").equalTo(user.getUid()).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//deal with data object
}
#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) {
}
});
OR use addValueEventListener
mReference.child("user").orderByChild("userId").equalTo(user.getUid()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//deal with data object
}
#Override
public void onCancelled(DatabaseError databaseError) {
//toastMsg(databaseError.getMessage());
Log.e(TAG, "onCancelled: " + databaseError.getMessage());
}
});
Use something like the below code which i am using in my application and it works -
public static void storagesSetup(final Context context){
if(!hasSignedInUser()) {
**your business logic here**
return;
}
// Write a message to the database
final DatabaseReference databaseRef = FirebaseDatabase.getInstance()
.getReference("cart").child(getCurrentUser().getUid());
// Read from the database
databaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
**put your business logic here**
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});
}
A Firebase Database query inspects the child nodes directly under the location that you execute it on. If you want to order on a child property of those nodes (i.e. use orderByChild()), that property must exist at a fixed path under each child nodes.
In your case, you have two nested dynamic children, which means you:
can query a known user for their results ordered by score
can't query across all users for their results ordered by score
If you want to allow the latter query, you'll need to change your data model to allow it. For example, by keeping a list of all results across all players:
ResultsTable:{
"-KbJtw467nl6p253HZ537" : {
"Name" : "name1",
"Email" : "something1#something.com",
"userid" : "fmXWU324VHdDb8v6h7gvNjRojnu33"
},
"-Kb012ls9iMnzEL723o9I" : {
"Name" : "name2",
"Email" : "something2#something.com",
"userid" : "pJtC45fW0MMi352UiPWnWdIS7h88"
},
"-Kb0aq0q25FJq38256SrC" : {
"Name" : "name3",
"Email" : "something3#something.com",
"userid" : "pJtC45fW0MMi352UiPWnWdIS7h88"
},
"-Kb0atopfK64F6jy124Qi1u" : {
"Name" : "name3",
"Email" : "something1#something.com",
"userid" : "pJtC45fW0MMi352UiPWnWdIS7h88"
}
}
Please get a idea from below code.
Order objects:
DatabaseReference mDatabaseReference = FirebaseDatabase.getInstance()
.getReference();
DatabaseReference node = mDatabaseReference.child("order")
node.orderByChild("timestamp").equalTo("-KZFQLVAv_kARdfnNnib")
.addValueEventListener(mValueEventListener);
private ValueEventListener mValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.i(TAG, "onDataChange: " + snapshot.getValue());
// Your code
}
#Override
public void onCancelled(DatabaseError error) {
Log.w(TAG, "onCancelled: " + error.getMessage());
}
};
This return the first order object. Hope you get the point Thanks! :)
Related
I am trying to search a "username" in firebase database but it always returns the else statement
mDatabaseref = FirebaseDatabase.getInstance().getReference("user_info");
mDatabaseref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child("username").child(usernamedatabasesend).exists())
{
Log.i("USERINFO","USER EXISTS");
}
else
{
Log.i("USERINFO","USER DOES NOT EXISTS");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mDatabaseref = FirebaseDatabase.getInstance().getReference("user_info");
mDatabaseref.push().setValue(uic);
the usernamedatabasesend is the Edittext value to send it to the database to check if that same value the user is entering is existing on the db or not
The Database node is like this
"user_info" : {
"-L-7QPKXFyoN-GlPxTTN" : {
"email" : "",
"name" : "",
"password" : "",
"username" : "ujjwalbassi"
},
"-L-7QPMyzXCqpWT0YLPM" : {
"email" : "",
"name" : "",
"password" : "",
"username" : "ujjwalbassi"
}
}
****UPDATE*********
This is the new code
mDatabaseref.orderByChild("username").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dataSnapshot1: dataSnapshot.getChildren())
{
userInfo userinfoclass = dataSnapshot1.getValue(userInfo.class);
String usernamegotunamn = userinfoclass.getUsername().toString();
if(usernamegotunamn.equals(usernamedatabasesend))
{
Log.i("YESONO","USEREXISTS"+"\n"+usernamegotunamn+"\n"+usernamedatabasesend);
}
else {
mDatabaseref.push().setValue(uic);
Log.i("YESONO", "USERDOESNOTEXIST");
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The if else is working but if the "IF" is true then else works with it too. but it shows that if the user exists or not.
Try this.
mDatabaseref.orderByChild("username").equalTo("ujjwalbassi").addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//data will be available on dataSnapshot.getValue();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
}
});
Reference : How to Search for data in Firebase Android
To check if the user exists by looping, you'll need to loop through each DataSnapshot and see if the username matches. To do this you need to, first, get a DataSnapshot of all the users, and then loop through each one:
mDatabaseref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot user : dataSnapshot){
if(user.child("username").getValue(String.class).equals(usernamedatabasesend)){
//The username matches!
Log.i("USERINFO","USER EXISTS");
return
}
}
}
#Override public void onCancelled(DatabaseError databaseError) {}
});
This isn't the best practice (Will get slow if you have a ton of users) but it is definitely a working solution. I recommend using #lovekush-vishwakarma's answer as a faster solution.
You cannot use exists() method to check whether a value exists or not. If you want to use exists() method, then you should consider change your database structure a little bit. Instead of having as a unique identifier the id that is generated by the push() method, just use the user name. Your database structure should look like this:
"user_info" : {
"ujjwalbassi" : {
"email" : "",
"name" : "",
"password" : "",
},
"anotherUserName" : {
"email" : "",
"name" : "",
"password" : "",
}
}
The important thing here is, when you add a new user to the database to check the userame for uniqueness. To verify if a user exists, you can use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userNameRef = rootRef.child("user_info").child(usernamedatabasesend);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
//do something
} else {
//do something else
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
userNameRef.addListenerForSingleValueEvent(eventListener);
Another approach will be to filter the database after usernamedatabasesend and get all the users with the same user name. This is not a good practice, to have users in your database which have the same user name. If you want to go with this, you can use orderByChild() method in a query like this:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query userNameQuery = rootRef.child("user_info").orderByChild("username").equalTo(usernamedatabasesend);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
//do something
} else {
//do something else
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
userNameQuery.addListenerForSingleValueEvent(eventListener);
If the user name contains a dot ., then you need to encode it in order to use it as a key in the database. To encode the user name please use the following mothod:
static String encodeUserName(String userName) {
return userName.replace(".", ",");
}
And to get it back, please use the following code:
static String decodeUserName(String userName) {
return userName.replace(",", ".");
}
I have a structure in the firebase with some keys, I would like to know how to update a field of the last key generated.
I need to retrieve the last key generated and update the data, how to do that ???
In Json format
What I would like to change "Status"
"-Kuxu1dX_aMcKZbqpGiQ" : {
"Status" : {
"status" : "Engano"
},
"data" : "26/9/2017 às 8h17",
"funcionario" : "João Cardoso",
"motivo" : "Carta",
"nome" : "Felipe Antunes",
"tempo" : -1506424666540,
"visita" : "null"
},
"-KuxuQuZzcTV5T-PHw18" : {
"Status" : {
"status" : "Engano"
},
"data" : "26/9/2017 às 8h19",
"funcionario" : "João Cardoso",
"motivo" : "Encomenda",
"nome" : "Felipe Antunes",
"tempo" : -1506424770025,
"visita" : "null"
}
To be able to make a change to an item, you'll first need to find that item with a query:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("7VCZ8oJSz...");
Query query = ref.orderByKey().limitToLast(1);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
childSnapshot.getRef().getChild("Status").setValue("New value");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "Query:onCancelled", databaseError.toException());
}
});
To achieve this, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference yourRef = rootRef.child("7VCZ8oJSz...");
Query query = yourRef.orderByKey().limitToLast(1);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dataSnapshot.child("Status").child("status").setValue("yourNewValue");
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
query.addListenerForSingleValueEvent(eventListener);
I created a helper class including the functions and processes I would like to perform over my data in FirebaseDatabase.
The following function was meant to get all Posts in posts Node in fireabseDataBase:
public static Jobs getAllJobs() {
Posts posts= new Posts();
postsDBRef= FirebaseDatabase.getInstance().getReference("posts").getRef();
postsDBRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot jobSnapshot: dataSnapshot.getChildren()) {
// TODO: handle the post
String key = jobSnapshot.getKey();
//here
Post post= jobSnapshot.child(key).getValue(Post.class);
// and here
posts.add(post);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.i(getClass().getName().toString(), ": " + databaseError.getMessage());
}
});
return posts;
}
in the onDataChange function I am trying to loop over the data and retrieve it, although while logging I do get data but the post object keeps giving Null
Here's How the data look like in firebase DataBase
{
"posts" : {
"-Kr9-ii-ArpC3fLuuGnb" : {
"address" : "sfhhfg",
"applied" : false,
"currency" : "le",
"description" : "ehdhyf",
"latitude" : 0,
"longitude" : 0,
"noOfWorkers" : 2,
"rating" : 0,
"reported" : false,
"salary" : "1250",
"title" : "rgchu",
"userId" : 0
},
"-Kr94BDkdEZrmxmjxv_Z" : {
/../
},
"-Kr9Dz3S0BQEYv4VO2l3" : {
/../
},
"-Kr9XqDPUvCRcv0lwFy_" : {
/../
}
}
}
and here’s what am getting from the Debugger in a single loop
DataSnapshot { key = -Kr9-ii-ArpC3fLuuGnb, value = {address=sfhhfg,
rating=0, title=rgchu, reported=false, description=ehdhyf, userId=0,
longitude=0, noOfWorkers=2, latitude=0, currency=le, applied=false,
salary=1250} }
Any idea what am I doing wrong?
After several trials
.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Job job = snapshot.getValue(Job.class);
System.out.println(job.getTitle());
}
}
#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) {
Log.i(getClass().getName().toString(), ": " + databaseError.getMessage());
}
});
Using .addChildEventListener was the only Solution for my issue, Still investigation the reason.
i have edited your code and it should work fine now, i have used the same code snippets in several projects before. make sure your pojo matches the json data, you can use this tool to make it easier for yourself.
and the most important thing , Don't use Firebase as functions that return values - it goes against it's asynchronous nature.make Firebase perform it's task and then within the closure (block) go to the next step.
P.S: before using ValueEventListener or ChildEventListener read the difference between them from here.
public void getAllJobs() {
Posts posts= new Posts();
postsDBRef= FirebaseDatabase.getInstance();
postsDBRef.child("posts").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot jobSnapshot: dataSnapshot.getChildren()) {
Post post= jobSnapshot.getValue(Post.class);
posts.add(post);
}
// go to next step from here e.g handlePosts(posts);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.i(getClass().getName().toString(), ": " + databaseError.getMessage());
}
});
}
This is my JSON Structure:
{
"users" : {
"userKey1" : {
"deviceToken" : "deviceTokenID",
"displayName" : "Name here",
"dob" : "28/6/2017",
"email" : "efg#wxy.com",
"gender" : "M"
},
"userKey2" : {
"deviceToken" : "deviceTokenID",
"displayName" : "Name here",
"dob" : "28/1/2017",
"email" : "abc#xyz.com",
"gender" : "M",
}
}
}
In my android Firebase file, I type this:
Query findUser = mDatabase.child("users").orderByChild("email").equalTo("abc#xyz.com");
findUser.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.i("findUser","Snapshot: " + dataSnapshot.toString());
}
#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) {
}
});
I get the following log:
06-28 22:06:50.190 30962-30962/in.sample.project I/findUser: Snapshot: DataSnapshot { key = users, value = null }
I do not know why I am getting null when cleary I have a child who's email node matches "abc#xyz.com".
You need a foreach loop to get the user in your findUser query because your query contains a collection.
Query findUser = mDatabase.child("users").orderByChild("email").equalTo("abc#xyz.com");
put this part in your eventlistener
....
public Iterable<DataSnapshot> getChildren (){
for (DataSnapshot child : parent.getChildren()) {
....
}
}
Needed to add security rules.
rules: {
"users" : {
".indexOn": "email",
}
}
I guess, that did the trick. Hope it helps someone. :)
I am having trouble with a firebase call that I want to compare if the value is simply true or false. Here is my attempt:
Firebase followingRef = currentUserPath.child("/following");
followingRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(final DataSnapshot dataSnapshot, String s) {
firebaseRef.child("people/" + dataSnapshot.getKey()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Boolean isFollowing = (Boolean) dataSnapshot.getValue();
if(isFolloiwng) {
User user = snapshot.getValue(User.class);
user.setUserId(dataSnapshot.getKey());
application.getFollowingRecyclerViewAdapter().add(user, application.getFollowingRecyclerViewAdapter());
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
...//OnChildChanged,Moved,etc... no code in here
At the path I want to reference in currentUserPath.child("following"); it looks like this:
EDIT: Replace Picture with actual JSON:
"users" : {
"10206287838487450" : {
"following" : {
"10208425049208936" : true,
"107214969710378" : false,
"1789986447904975" : true
},
"id" : "ae80f030-dea0-4909-944f-0e490847b6ab",
"name" : "Stephen",
"posts" : {
"-KN_oJAgTNJHwJbqY3qk" : true,
"-KN_oN9_Xmw5ULnBRYM7" : true,
"-KN_obYGug9Tdrzufbqc" : true,
"-KNefMk2nX0sOsUx0btx" : true
},
"userId" : "10206287838487450"
},
"people" : {
"10206287838487450" : {
"id" : "9e7ee838-a60a-4588-bc1c-93b98f74356d",
"name" : "Bob",
"userId" : "10206287838487450"
},
"10208425049208936" : {
"id" : "fe6f97e3-0efb-4afb-a322-a1c586f75fb7",
"name" : "Jack",
"userId" : "10208425049208936"
},
"107214969710378" : {
"id" : "ae80f030-dea0-4909-944f-0e490847b6ab",
"name" : "Rick",
"userId" : "107214969710378"
},
"108421236267392" : {
"id" : "c72b35d9-380b-4552-8b05-7426d378fa14",
"name" : "Tommy",
"userId" : "108421236267392"
},
"1112460595485164" : {
"id" : "383692f0-0aba-4d29-afb8-80beefe678c6",
"name" : "Stanley",
"userId" : "1112460595485164"
},
"1789986447904975" : {
"id" : "1ae43255-c040-4b1e-959e-fcdf03e13a45",
"name" : "Link",
"userId" : "1789986447904975"
}
},
I'm very confused because every time I try to cast the dataSnapshot.getValue() to a Boolean, I always get isFollowing = true which is clearly not correct because in my data, there is only 2 values that are true as seen above, not all 3. The confusing thing is how come I can't retrieve the Boolean correctly. I have tried to do Boolean isFollowing = (Boolean) dataSnapshot.getValue(Boolean.class) also but this doesn't work. The Firebase documentation says that when retrieving data, a Boolean can be a type of data we can retrieve but I can't seem to retrieve it correctly. Any help would be appreciated. Thanks!
Works for me:
Firebase ref = new Firebase("https://stackoverflow.firebaseio.com/38671701/users");
Firebase currentUserPath = ref.child("10206287838487450");
Firebase firebaseRef = ref.child("10206287838487450");
Firebase followingRef = currentUserPath.child("/following");
System.out.println("Listening for children on "+followingRef);
followingRef.addChildEventListener(new ChildEventListenerBase() {
#Override
public void onChildAdded(final DataSnapshot dataSnapshot, String s) {
firebaseRef.child("people/" + dataSnapshot.getKey()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Boolean isFollowing = (Boolean) dataSnapshot.getValue();
System.out.println(dataSnapshot.getKey()+"="+isFollowing);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
});
Listening for children on https://stackoverflow.firebaseio.com/38671701/users/10206287838487450/following
10208425049208936=true
107214969710378=false
1789986447904975=true
Try something like this:
Firebase followingRef = currentUserPath.child("following");
followingRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot snapshot: dataSnapshot.getChildren()){
Log.d(TAG, snapshot.getKey();
Log.d(TAG, snapshot.getValue();
//Do your operations here
}
}
}
Change a model class
boolean value
To
Boolean value