How to perform search in a FirebaseDatabase? - android

Description
My Firebase NoSQL Database should look somewhat like this:
A user Java model should get pushed whenever a new user signs in.
Problem
How to check if the user with the email address already has an account? Since the email address is at: Root > PushID > email; and push ID is automatically generated, I am not sure on how to iterate on all push ID's and check if any of them has its email key set to the specified value.
I have read the documentation but unable to figure out how to solve this problem.
Learning from Shubhank's answer
Firebase Methods which involve a child can be applied to any of its children irrespective of its level in the hierarchy i.e. not limited to immediate children.
In this problem, the child to be searched was 2 levels below the common parent. The first level child can be ignored and query methods can be directly applied on the target child.

You should first make a model class for the user
class User {
public String email;
public String name;
}
Then get the users from the db and map them into User objects
Simple loop through all results query
FirebaseDatabase database = FirebaseDatabase.getInstance();
// i don't know the end point since you have not specified it in the image
database.getReference("myUsersEndPoint").addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
User user = data.getValue(User.class);
if (myField.getText().toString().eqaulsIgnoreCase(user.email)) {
// exist
}
}
}
#Override
public void onCancelled(DatabaseError databaseError)
Log.w("MyApp", "getUser:onCancelled", databaseError.toException());
}
});
Searching only for specific Values
In this example, we use the orderByChild and equalTo method to limit result to specific child value
FirebaseDatabase database = FirebaseDatabase.getInstance();
// i don't know the end point since you have not specified it in the image
database.getReference("myUsersEndPoint").orderByChild("email").equalTo("emailToSearchhere").addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
// here the user will have the specified email only
}
}
#Override
public void onCancelled(DatabaseError databaseError)
Log.w("MyApp", "getUser:onCancelled", databaseError.toException());
}
});

Related

Retrieve Firebase data who have specific child

Please check my database image. I want to select and display all users who have parent = chris
my database image
To retrieve the users that contain parent : chris, you can do the following:
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("users");
reference.orderByChild("parent").equalTo("chris").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot datas: dataSnapshot.getChildren()){
String name = datas.child("name").getValue(String.class);
String key = datas.getKey();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
orderByChild.equalTo is a query that will retrieve all the nodes that contain parent equal to chris.
Since you tagged this as a android studio question I assume you are using the Firebase SDK.
You should check out the documentation, where they explain how you can query in a lot of languages with very nice examples.

firebase get value from uid after unkown uid

CABARAN is an unknown Uid. it is not a text. Right now I have the uid, and I want to get value for the tajukPenuh.
This is the code and I still can't get the value.
FirebaseDatabase.getInstance().getReference().child("karangan").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
Karangan karangan = child.child(karanganID).getValue(Karangan.class);
if (karangan != null) {
String tajukPenuh = karangan.getTajukPenuh();
holder.getTextViewKaranganID().setText("Karangan Tajuk: " + tajukPenuh);
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
You could in theory do a query like this:
FirebaseDatabase.getInstance().getReference().child("karangan")
.orderByChild("-LYgFIl4Xiv_Ls51Slvh/uid").equalTo("-LYgFIl4Xiv_Ls51Slvh")
.addListenerForSingleValueEvent(new ValueEventListener() {
But the problem is that you'd need a lot of indexes in your rules, which may be technically possible, but is unfeasible for most real usage.
Your current data structure makes it easy to find all the child nodes for CABARAN, but it does not make it easy to find CABARAN for a given child node. To allow that use-case to run efficiently, you should expand your data structure with a so-called reverse index that maps back to CABARAN from the value that you know. So something like:
"myIndex": {
"-LYgFIl4Xiv_Ls51Slvh": "CABARAN",
"-LzfFIl4Xasas51Slads": "CABARAN",
"-Lasddas981398asdh1h": "CASITWO"
}
This is an additional data structure, that you will have to keep up to date when you're writing the rest of the data. But with this structure, it now becomes very easy to determine that -LYgFIl4Xiv_Ls51Slvh maps to CABARAN.
For more on this, see my answer here: Firebase query if child of child contains a value

firebase data change method in android studio

how email's value change from "app-user/users"?
Firebase state :
this isn't web language, i use javacode and xml of androidstudio.
i'm tryed under code.
databaseReference.child(app-user).child(user).orderByChild("email").equalTo("user4~~")
I don't know what to do next.
To get all users whose email address starts with user4:
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference().child("app-users/users");
Query usersQuery = usersRef.orderByChild("email").startAt("user4").endAt("user4\uF7FF");
usersQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot userSnapshot: dataSnapshot.getChildren()) {
System.out.println(userSnapshot.getKey()+": "+userSnapshot.getChild("displayName").getValue(String.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
To understand the usersRef.orderByChild("email").startAt("user4").endAt("user4\uF7FF") query, read it as:
Take all child nodes of usersRef and order them by their email property.
Then find the first child node that starts with user4.
Then return each child node, until you find a child that starts with .endAt("user4\uF7FF") (or further).
In this the \uF7FF is no magic code, but just the last known Unicode character. So by combining .startAt("user4").endAt("user4\uF7FF"), you're building a startsWith operator.

Firebase user details are not retrieved in Android

I am storing user details 'firstname' and 'lastname' in UserNode. But when i want to retrieve that details then no data is being retrieved. I tried almost all solutions on the internet but nothing solved my problem. Here is my code for retrieving data of the current user:
FirebaseUser userr = FirebaseAuth.getInstance().getCurrentUser();
if (userr != null) {
String name = userr.getDisplayName();
Log.e("value", name);
}
but it says "println needs a message"
I also tried with this but nothing happened:
DatabaseReference DataRef;
DataRef = FirebaseDatabase.getInstance().getReference().child("UserNode");
DataRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String acctname = (String)dataSnapshot.child("firstname").getValue();
Log.e("name", acctname);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
]1
Please help me I am stuck with it
You're reading a collection of user with a ValueEventListener. As the [Firebase documentation for reading lists with a value event](Listen for value events) explains:
While using a ChildEventListener is the recommended way to read lists of data, there are situations where attaching a ValueEventListener to a list reference is useful.
Attaching a ValueEventListener to a list of data will return the entire list of data as a single DataSnapshot, which you can then loop over to access individual children.
Even when there is only a single [child node], the snapshot is still a list; it just contains a single item. To access the item, you need to loop over the result.
So in your code:
DatabaseReference DataRef;
DataRef = FirebaseDatabase.getInstance().getReference().child("UserNode");
DataRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String acctname = (String)childSnapshot.child("firstname").getValue();
Log.i("name", acctname);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Using FirebaseUser:
FirebaseUser implements UserInfo and in UserInfo's getDisplayName() documentation says
Returns the user's display name, if available.
So, it is possible that FirebaseUser.getDisplayName() return null when display name is not set. In that case Log.e() receives null as message and therefore prints println needs a message
Using your own structure:
Instead of using type conversion use getValue(Class<T>) like so:
String acctname = dataSnapshot.child("firstname").getValue(String.class);
Please, read how to retrieve data from firebase. I think you have a problem because you don't have Class Model.
Your steps:
Create model UserModel with firstname and lastname field
Use listener (example from docs):
// Attach a listener to read the data at our posts reference
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Post post = dataSnapshot.getValue(Post.class);
System.out.println(post);
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
See other answers: How to retrieve data from one single userID Firebase Android and retrieving data from firebase android

How to get max Id of items on Firebase Database?

My DB :
I create new item like this:
mFirebaseDatabase.getReference(Api.CREDITS).child(String.valueOf(item.getId())).setValue(item);
but when I'll create a new item , I need to set his ID... how to determinate last id of items in the list in Firebase?
The easiest way is probable:
var latest = ref.child("credits").orderByKey().limitToLast(1);
latest.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String latestKey = childSnapshot.getKey();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "onCancelled", databaseError.toException());
}
})
But this is going to lead to problems like:
this operation will not work when the user is without network connectivity
when multiple users are trying to add children at (almost) the same time
This is one of the many reasons why Firebase recommends against using such sequential numeric IDs and uses push IDs.
Read the documentation on dealing with lists and this blog post: https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html

Categories

Resources