I have this database where I store user stuff. How do i get DataSnapshot only if uname is "user 1"
Database image here
You need to query on realtime database. You can query by giving a ref: ref('uploads'), order it by the field you want: orderByChild('uname') and then put your filter: equalTo('user 1')
firebase.database()
.ref('uploads')
.orderByChild('uname')
.equalTo('user 1')
.once('value')
.then(snap => {
snap.forEach(uploadSnap => {
console.log(uploadSnap.val());
});
})
.catch(error => {
console.log(error)
});
How do I get DataSnapshot only if uname is "user 1"
To be able to get elements from a Firebase Realtime Database where the "uname" property holds the value of "user 1", you need to use a query. To be sure that the DataSnapshot object you are looking for actually returns some results, then you should call exists(), as in the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uploadsRef = rootRef.child("uploads");
Query queryByUserName = uploadsRef.orderByChild("uname").equalTo("user 1");
queryByUserName.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot userSnapshot : task.getResult().getChildren()) {
if(userSnapshot.exists()) {
String uname = userSnapshot.child("uname").getValue(String.class);
Log.d("TAG", userSnapshot);
}
}
} else {
Log.d("TA"G, task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
Since "user 1" already exists in the database, the result in the logcat will be:
user 1
Related
that's my database
{
"users" : {
"-MdgDcU3Zb-TiLlTwfwU" : {
"email" : "t1#email.com",
"fname" : "test",
"lname" : "1",
"password" : "t1",
"phoneno" : "304*******"
},
"-MdgNDN23XCTyB4DsF4W" : {
"email" : "t2#email.com",
"fname" : "test",
"lname" : "2",
"password" : "t2",
"phoneno" : "333*******"
}
}
}
that's the login activity's code
DatabaseReference reference= FirebaseDatabase.getInstance().getReference("users");
Query checkUser = reference.orderByChild("phoneno").equalTo(userphoneno);
checkUser.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
//editTextphoneno.setError(null);
//editTextphoneno.setErrorEnabled(false);
String passwordFromDB =snapshot.child(userphoneno).child("password").getValue(String.class);
if(passwordFromDB.equals(userpassword)){
//editTextphoneno.setError(null);
//editTextphoneno.setErrorEnabled(false);
Intent i = new Intent(Login_page.this, Bottomnav.class);
startActivity(i);
finish();
}else{
editTextpassword.setError("Invalid Password");
editTextpassword.requestFocus();
}
}else{
editTextphoneno.setError("Invalid Phone Number");
editTextphoneno.requestFocus();
}
}
I want the user to login through his phone number and password but every time, after entering phone no and password I click on login, the app crashes. What I have understood is that may be the user's phone number and password is not being retrieved successfully.
When you are using the following query:
DatabaseReference reference= FirebaseDatabase.getInstance().getReference("users");
Query checkUser = reference.orderByChild("phoneno").equalTo(userphoneno);
It means that you are searching the "users" node, for all users who have the "phoneno" equal to "userphoneno". This also means that such a query may potentially return multiple results. Even if the query returns a single result, you'll need to loop through the DataSnapshot object using getChildren() method, as in the following lines of code:
checkUser.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot ds : task.getResult().getChildren()) {
String passwordFromDB = ds.child("password").getValue(String.class);
Log.d("TAG", passwordFromDB);
//Add your logic
}
} else {
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
Please see that inside onComplete, in order to get the password, there is no need for a .child(userphoneno) call, as the "password" is already a child of the DataSnapshot object.
More important, never store sensitive data as passwords in plain text. Malicious users might take advantage of that. Use Firebase Authentication for that and secure the database using Firestore Security Rules.
I have converted to Firebase for my Android development as I want to utilise the many features of Firebase (Notifications, Messaging, Storage etc), however, I am having difficulty receiving data from Firebase and cannot find detailed information online. Yes, I have tried the documentation but it does not explain the events I am experiencing.
I want to retrieve all the data that I have an insert it into an arraylist of objects. Here is a static example:
users[i] = new User("James" + (i*2.5), "Hmack00" + (i*2), "https://firebasPic_2019.03.03.05.26.35.jpg.jpg?alt=media&token=cf", "United Kingdom");
Database:
{
"Users" : {
"4PdlTlv3qjZ3BmDvrJyUut9Fnq43" : {
"Country" : "xx",
"Fullname" : "hh",
"ProfilePicture" : "htm/o/Images%2FSearchAdapter%2F4PdlTlv3qjZ3BmDvrJyUut9Fnq43%2FProfilePicture%2FProfilePic_2019.03.06.10.47.54.jpg.jpg?alt=media&token=b647708e-c6d5-4b45-bef0-3dc40301b73a",
"Username" : "hmack001"
},
"COg4r4io9hezhFpmK3adPucUXA93" : {
"Country" : "spain",
"Fullname" : "nat",
"ProfilePicture" : "hcom/o/Images%2FSearchAdapter%2FCOg4r4io9hezhFpmK3adPucUXA93%2FProfilePicture%2FProfilePic_2019.03.06.19.14.17.jpg.jpg?alt=media&token=8620b321-5cef-42f0-a828-dbb7c37c8e7d",
"Username" : "nat"
},
"Tw1xRxViygNsLqrQiaaMAvAduIu1" : {
"Country" : "uk",
"Fullname" : "harvey\n",
"ProfilePicture" : "t.com/o/Images%2FUsers%2FTw1xRxViygNsLqrQiaaMAvAduIu1%2FProfilePicture%2FProfilePic_2019.03.03.05.26.35.jpg.jpg?alt=media&token=c290e75a-5f92-4271-bcb5-c644fe1b14ef",
"Username" : "RGB"
},
"vOxr1RoDqgWogKK1lp9pfpTHc6w2" : {
"Country" : "scotland ",
"Fullname" : "greg greg",
"ProfilePicture" : "ot.com/o/Images%2FSearchAdapter%2FvOxr1RoDqgWogKK1lp9pfpTHc6w2%2FProfilePicture%2FProfilePic_2019.03.04.12.30.22.jpg.jpg?alt=media&token=27b024cf-0691-4121-8a27-26acf101ebc2",
"Username" : "greg"
},
"xecUOPeyMcQaQrgkU9ouDgK90Ai1" : {
"Country" : "ggh",
"Fullname" : "Da apply ",
"ProfilePicture" : "2FProfilePic_2019.03.03.04.58.50.jpg.jpg?alt=media&token=f35854c2-3ff9-4d18-9f7a-10c13f066c68",
"Username" : "gg"
}
}
}
Here is my code and I will explain my errors after (I have left in 'zombie' code, to show the attempts that I have made)
//Firebase Variables
private FirebaseDatabase mFirebaseDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
//Firebase Data
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
userId = mAuth.getCurrentUser().getUid();
myRef = mFirebaseDatabase.getReference().child("Users").child(userId);
//Firebase Data
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) { //Function called every time a change is made to the database
showData(dataSnapshot);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { //Function called when there is an error in the database/ with the call
Log.d("Print","Cancelled Firebase: " + databaseError.toString());
}
});
}
private void showData(DataSnapshot dataSnapshot) {
int userCount = 5;
int i = 0;
for (DataSnapshot ds : dataSnapshot.getChildren()) {
//User user = new User();
//User user = new User(); //Get Count of Firebase Users
//user = new User();
if (ds.child(userId).exists()) {
/*user.setFullname(ds.child(userId).getValue(User.class).getFullname()); //set the full name
user.setUsername(ds.child(userId).getValue(User.class).getUsername()); //set the username
user.setProfilePicture(ds.child(userId).getValue(User.class).getProfilePicture()); //set the profile picture
//Display Information
Log.d("DataSnapchat Test", "ShowData Name: " + user.getFullname());
Log.d("DataSnapchat Test", "ShowData Username: " + user.getUsername());
Log.d("DataSnapchat Test", "ShowData Picture: " + user.getProfilePicture());
ArrayList<String> userArrayList = new ArrayList<>();
userArrayList.add(user.getFullname());
userArrayList.add(user.getUsername());
userArrayList.add(user.getProfilePicture());
*/
String fullname = (String) ds.child(userId).child("Fullname").getValue();
Toast.makeText(this, "Fullname: " + fullname, Toast.LENGTH_SHORT).show();
//UserListAdapter adapter = new UserListAdapter(this, R.layout.find_profiles_search, userArrayList, mProfileSearch);
//mListView.setAdapter(adapter);
i++;
}
}
}
When I debug the code the showData function is never called and neither functions within the Value Event Listener are called, is this an Async Problem?
Currently I am trying to fetch data and insert it into a variable (Literally any data, once I have a working query I can convert it to fit by manipulating child fields etc).
Question: Does the addValueListener only work when data is changed in the database? If so then what is the alternative, if not then why are the functions not operating.
I do not recieve any errors and nothing is logged to the console.
I want to put my database into an array list, I know that I shouldnt use getChildren to do this, put I am trying to test if I can get any data before I try and get all the data.
You have some really weird loops in showData(). Since you're attaching a ValueEventListener to the node of the specific user, you can just look up the property values for that specific user:
myRef = mFirebaseDatabase.getReference().child("Users").child(userId);
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("OnDataChange", dataSnapshot.getKey());
Log.d("OnDataChange", dataSnapshot.child("Fullname").getValue(String.class));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("Print","Cancelled Firebase: " + databaseError.toString());
}
});
I am using both Firebase Authentification and Firestore for my Android app. What I am trying to do is the following:
the user signs in
if it's the first time the user signs in a document named by his uid is created
if the user has already signed in before (hence document named by uid already exists) then I load some further data.
Here's my logic to solve this:
get the FirebaseUser from FirebaseAuth instance
from the FirebaseUser I get the uid
build a DocumentReference with this uid
use get() query on the DocumentReference
if DocumentSnapshot is != null then user already exists in firestore
if DocumentSnapshot == null the user doesn't exist and I create it in firestore
I was testing the code below:
FirebaseUser user = mAuth.getCurrentUser();
if(user != null) {
// get uid from user
String uid = user.getUid();
// make a query to firestore db for uid
DocumentReference userDoc = db.collection("users").document(uid);
userDoc.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document != null) {
Log.d(LOG_TAG, "DocumentSnapshot data: " + task.getResult().getData());
} else {
Log.d(LOG_TAG, "No such document");
}
} else {
Log.d(LOG_TAG, "get failed with ", task.getException());
}
}
});
}
When uid exists in firestore I get the log message with appropriate data but when it doesn't I get the following exception and I can't find a way to get to use DocumentSnapshot.exists():
java.lang.IllegalStateException: This document doesn't exist. Use DocumentSnapshot.exists() to check whether the document exists before accessing its fields.
Can anyone help me understand what I am doing wrong ?
Thanks a million ! :)
The object returned by get() is a DocumentSnapshot not the document itself. The DocumentSnapshot is never null. Use the exists() method to determine if the snapshot contains a document. If exists() is true, you can
safely use one of the getXXX() methods (in your case, getData() for a map) to obtain the value of the document.
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot snapshot = task.getResult();
if (snapshot.exists()) {
Log.d(LOG_TAG, "DocumentSnapshot data: " + snapshot.getData());
} else {
Log.d(LOG_TAG, "No such document");
}
} else {
Log.d(LOG_TAG, "get failed with ", task.getException());
}
}
This is my structure:
{
users: {
"aufgdheyrl": {
id: "152",
name: "Joe Jackson",
level: "A2",
point: 120.0
},
"yudwjwnecj": {
id: "134",
name: "Samnuel Jackson",
level: "B3",
point: 80.5
},
"fuwhdkcjdo": {
id: "188",
name: "Jack Jack",
level: "B2",
point: 50.0
}
}
}
this is my code for get the selected user only if its level or point value is greater than another one. But the query doesnt't work.
I use mDatabase.child("users").child(id_client) for getting the reference of the selected user.
DatabaseReference mUserRef = mDatabase.child("users").child(id_client);
Query query1 = mUserRef.orderByChild("level").startAt(level);
Query query2 = mUserRef.orderByChild("point").startAt(point);
query1.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "datasnaphot " + dataSnapshot.toString());
User user = dataSnapshot.getValue(User.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
}
});
query2.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "datasnaphot " + dataSnapshot.toString());
User user = dataSnapshot.getValue(User.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
}
});
for example I have this values:
String id_client = "aufgdheyrl";
double level = 200.0;
String point = "A1";
both query1 and query2 return object but query1 must have null value and not user object
Idem if I have level="B1", the query2 return user object and not null value
Firebase queries are executed on a list of nodes, and then filter each child node in that list on the property that you specify.
With mDatabase.child("users").child(id_client) you're already in the node of a specific user:
"aufgdheyrl": {
id: "152",
name: "Joe Jackson",
level: "A2",
point: 120.0
}
Calling orderByChild() here will try to filter each child node of this JSON. Since the child nodes are simple values (e.g. point: 120.0), the filter will not match anything.
You're more likely to get the results you want if you query the list of users for a level:
Query query = mDatabase.child("users").orderByChild("level").startAt("B3");
This query will return a list with yudwjwnecj.
I have this rule in my firebase database
"Item":{
"$userId": {
".write": "auth != null && $userId === auth.uid"
}
}
I have this data
Item
nXQw4a2jlMg34567811glaTD0bE2
-KNJLSxfR_S8AeLj0v7d
height:20
id:-KNJLSxfR_S8AeLj0v7d
When i write the below query, everything is ok.
mDataBase = FirebaseDatabase.getInstance().getReference(FirebaseConstants.ITEM);
query = mDataBase.orderByChild("userId/height").limitToLast(2);
But the below query returns zero
public void getItems(String key){
//key is -KNJLSxfR_S8AeLj0v7d
DatabaseReference reference = FirebaseDatabase.getInstance().getReference(FirebaseConstants.ITEM);
reference.orderByChild("userId/id").equalTo(key).addValueEventListener(new MyEventListener());
}
My listener
private class MyEventListener implements ValueEventListener{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot != null){
Log.d("size is "+dataSnapshot.getChildrenCount()) // returns 0
for(DataSnapShot entry: dataSnapshot){
Item item = entry.getValue(Item.class);
Log.d("height is "+ item.getHeight())
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
}
Why is it returning zero and already i have data in my firebase Db?
There are a few small problems with your code:
There is no child userId, that you are trying to order/filter on: orderByChild("userId/height"). So that means the result will be empty.
You cannot loop over a snapshot (I'm surprised that even compiles). Instead you should loop over its children: for(DataSnapShot entry: dataSnapshot.getChildren()) {...
You're using a query, but your code would be more efficient and a lot more scalable if you'd simply look up the item by their key: reference.child(key).addValueEventListener(...