SQL Query to Firebase query - android

The SQL query that I want to apply is:
SELECT time FROM Appointment WHERE date = "3/15/2019" AND time = "9:00AM"
but I don't know how to translate it in Firebase. I am using Firebase in Android Studio. My goal here is to prevent date and time duplicate since the app that I'm developing is an online appointment.
Database:
Appointment
angelcrist
aptype: "Objective(Computerized)"
date: "3/15/2019"
name: "Hephep Horray"
time: "9:00AM"
miriammejia
aptype: "Objective(Computerized)"
date: "3/5/2019"
name: "Romz Ysmael"
time: "9:00AM"

There is no way you can do this with the Firebase realtime database. It does not have the capability to perform filtering on multiple conditions. If you have a SQL background, I can say that there are no "multiple where clauses" in Firebase. If you want to check for matches on multiple properties, you'll have to create a composite field as explained in my answer from the following post:
How to sort Firebase records by two fields (Android)
If you consider at some point to try using Cloud Firestore, please note it allows you to filter on multiple conditions. Chaning multiple whereTo calls are working perfectly fine.

First fetch your Appointment data for that particular date using below query, and loop through dataSnapshot childrens to check if you have the time available for that date.
reference.orderByChild('date').equalTo("<yourDate>")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot snap: dataSnapshot.getChildren()) {
//Check for time here
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Related

Unable to retrieve Friend Key by his email Using FIrebase Realtime Database

Database like this
Users
+oagnpangnangpadngn
+psdpgpsdnpgndpsngpndap
+pdgpjdpsgpdsjpgjpsdjpg
--letssupposemyfriendkey <----- I want this key
--name Ahsan
--email test#gmail.com
Now As you can see there is 2 child in each User.
I have already setup an on click button who get the email from layout when I input it in Edit Text. So mainly I want use that email I inputted to get User Key of that email .
e.g I inputted ----> test#gmail.com
Now how do I search users for this email and then get the key of user who has this email?
I am not Using Firestore or Cloud Functions, so if possible don't give me answers for that Im using Firebase Realtime Database in Android Studio using Java (Not Kotlin).
What you're trying to do requires the use of a database query. For example, here is how to find all users with a given ``email` value:
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("Users");
Query friendQuery = usersRef.orderByChild("email").equalTo("test#gmail.com");
friendQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot friendSnapshot: dataSnapshot.getChildren()) {
System.out.println(friendSnapshot.getKey()); // letssupposemyfriendkey
System.out.println(friendSnapshot.child("name").getValue(String.class)); // Ahsan
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
}
I highly recommend spending some time in the Firebase documentation on sorting and filtering, taking the Firebase codelab for Android developers, and reading previous questions about Firebase queries.

Retrieve and check whether a particular user enter email is present in firebase

I am developing an android application and using Firebase to store my data. I want to query the firebase instance to check whether the user entered email address matches one of the email in Firebase. Attaching the Firebase backend data.
My requirement is, I want to loop through the "guardians", which is the direct child of the Database instance and check whether the user entered email matches any one of the email address in that child. In the attached image, if the user entered email matches either "ram#gmail.com" or the other one, I want to do something.
databaseReference = FirebaseDatabase.getInstance().getReference().child("guardians");
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot data: dataSnapshot.getChildren()){
if (**I am unable to figure out how to search through entire guardians child for the email**) {
} else {
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
I am unable to figure out how to search through the entire guardians child to see whether the email matches the user entered email. Any help is appreciated. Thanks in advance.
If you made your current approach work (it's a matter of adding the correct if statement) you'd be downloading the entire list of users, just to check if a specific email address is in use. This is incredibly wasteful of bandwidth, especially as your user list grows.
You should instead use a Firebase Database query to only return the user with the requested email address:
databaseReference = FirebaseDatabase.getInstance().getReference().child("guardians");
Query query = databaseReference.orderByChild("guardianEmail").equalTo("guardian#example.com");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
... the email address is already in use
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Be sure to add an index for the guardianEmail field, as otherwise you'll still end up downloading all data for the query.
Note that this topic has been covered quite a few times before, and there are better ways to do this check. Most of these involve creating a so-called inverted index, where you use the (encoded) email address of the user as the key. With that structure you can prevent duplicates in Firebase's server-side security rules, which is even more efficient.
For more on this and other approaches, see:
Enforcing unique usernames with Firebase simplelogin
Firebase android : make username unique
How do you prevent duplicate user properties in Firebase?
Usernames with Firebase Simple Login (email/password)
What Firebase rule will prevent duplicates in a collection based on other fields?

Retriving Data From Firebase In DataSnapshot ( Not In Sequence )

I saved the data into Fire base but when I retrieve it. The data is not in the sequence.
Here Data Is Saved In Accurate Sequence:
But when I retrieve data lost its sequence:
Here is my code for retrieving Data
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users").child(Autho_User.getUid()).child("Data");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println(" Value = "+dataSnapshot.toString());
}
(Printed it just to check values) Data is not in the sequence even I get it through
dataSnapshot.getvalue();
Hope so you got my question. I need the data in sequence
Firebase stores JSON data. By definition the children under a node in JSON are unordered. It is only when the data is displayed or retrieved that it gets an order. So the first screenshot that you show is just the order in which the Firebase Database console display it.
If you want to get the data in a specific order in your application, you need to do two things:
Execute a query that returns the data in that order.
Ensure that your code maintains that order.
The code you shared does neither 1 nor 2, so the order in which the data is printed is anybody's guess. Usually it will be in lexicographical order of the keys, but it is undefined.
To learn how to order/filter data, read the Firebase documentation on ordering and filtering. To learn how to maintain the order of items when you use a ValueEventListener, read the Firebase documentation on listening for value events. When you combine these two, you get:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users").child(Autho_User.getUid()).child("Data");
Query dataOrderedByKey = ref.orderByKey();
dataOrderedByKey.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
System.out.println("Key = "+childSnapshot.getKey()+" Value = "+childSnapshot.toString());
}
}
...
This is an incredibly common mistake/question, so here are some previous questions for reference:
How to Convert Firebase data to Java Object...?
Ordering of data with Firebase Android
Firebase returning keys of child node in different orders on different devices/Android versions
How to sort by children key value in firebase?
Firebase .getvalue not in the same order as database
Order by date in negative timestamp is not working in Firebase

Lazy loading on firebase?

I am trying out firebase database and I was checking the recommended way of modeling many to many or one to many relationships.
Say I have this relationship between post and user:
user has many posts.
This is my approach for the model design:
class User{
List<String> postIds;
...
}
class Post{
String userId;
....
}
This is according to the firebase documentation here.
I like the design instead of embedding posts created by a user under user collection like the mongodb style this design is flat; so later time if we want to fetch only users on the system we dont have to pull the posts under the users as well.
But my doubt with this design is even embedding the ids within the posts could be a problem later on; imagine I have 100 users with 1000 posts each. If I want to show list of users I have to pull 100 users which means I have to pull 100,000 post ids.
Is there any lazy loading concept on firebase? ie when I fetch a user entity the postIds should not be loaded automatically; it should be loaded on demand.
There is no "lazy loading" or "load on demand" construct present in Firebase at the moment. All the data under a location is read and transferred on access. One thing you can do is separate out the User and UserInfo to two different branches so you can access users separately without pulling in the excessive data.
class User {
String id;
String name;
String gender etc.
}
class UserInfo {
List<String> postIds;
Other info maintained per user
}
In this way, you can read the users without pulling extra information.
An important rule in Firebase is to have the data as flatten as possible. You can take a look at this post, Structuring your Firebase Data correctly for a Complex App, for a better understanding.
Because there is no way in the Firebase Database to download just one property of each node, the single way to achieve this is to use a new node that hosts all those ids. So if you want an efficient way to verify the existens of an id or to count all the users, download just the list of ids. For good measure you should keep precisely that list of ids in the database.
To get all those ids, you can use this code:
DatabaseReference postRef = FirebaseDatabase.getInstance().getReference().child("Post");
postRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
String uId = ds.getKey();
Log.d("TAG", uId);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Hope it helps.

Firebase Database select by inner field

I have some difficulties building a query for selecting data in firebase database.
My database structure is like this:
I need to get all users which have contact ghopper. Here the result is alovelace and eclarke. But I really have no idea how to do this simple query in Java.
Thank you for your help!
You'd use Firebase Database queries for that:
DatabaseReference usersRef = FirebaseDatabase.getInstance().ref("users");
Query query = usersRef.orderByChild("contacts/ghopper").equalTo(true);
// My top posts by number of stars
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
System.out.println(snapshot.getKey());
}
}
But this requires that you define an index for each user, which doesn't scale. That is because the structure you have now is meant to allow to easily determine the users for a chat room, and you're trying the opposite.
To efficiently allow getting the chat rooms for a user, you should structure your data so that it also keep a list of users for each chat room. This is often called a secondary/reversed/inverted index.
For more examples of this see:
Firebase query if child of child contains a value
my answer on modeling many-to-many relationship in AskFirebase

Categories

Resources