How to retrieve data from firebase database without DataSnapshot? #AskFirebase - android

This my database in firebase
I want to get the value of page which is equal to 200.
When I tried like that:
DatabaseReference my= userid_database.child("Books").child("Book 1").child("Page");
System.out.println(my);
Output:
https://my-proje-book-timer.firebaseio.com/qpPLvgpM0TMF6vz4Kqw8QaYroG83/Books/Book%201/Page
When I tried like that:
DatabaseReference my= userid_database.child("Books").child("Book 1").child("Page").getKey();
System.out.println(my);
Output:
Page
I don't want to use this:
my.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String text = dataSnapshot.getValue(String.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Because I want to get all values for each Book pages and make a calculation with these values. In this way, I couldn't get the values outside of the method.

If you don't want to use a listener, you can use the REST API to easily make an HTTP query to find the data you want, assuming that it's readable without authentication. If you need authentication, it gets more difficult.
But you're really better off just learning now to make the listeners work for you, even if you're not accustomed to that kind of processing.

Related

How to set activity layout based on user type / role?

I am working on an Android app with 2 types of users (doctors and patients), and I want each type to have their own UI. For eg, doctors must see ' Add days off' and patients must see ' Book appointment' . Somehow I don't get anywhere with whatever I try.
I also use Firebase Auth and Realtime Database which makes the user type retrieval kinda tricky. So far I've tried a lot of Async classes, methods, variables, shared preferences, retrieving data while on launcher splash screen.
The best I got is getting the user to login, it shows the good layout, then I start the app again and it shows the wrong layout. Somehow I noticed it just works on the second run, but not always so the behaviour is unpredictable to me at least. But at least the user type from the database is retrieved.
I have a class that extends Application, which checks if there's an user authenticated and then redirects the user to either LoginActivity, or MainMenuActivity.
I have created a method that retrieves the Firebase Auth user data from Realtime Database, looping through both Doctors and Patients 'children' until it finds the current user email and gets its type. Since Realtime Database is asynchronous, the methos gets an interface as an argument, and after the loop, the I call the interface's method, which sets a static boolean variable (isUserDoctor).
Before setting the content view (with 2 possible layouts), I call the function described before and it works the way I first mentioned, which is not good.
The method that retrives data
public void getUserType(final DataStatus dataStatus) {
currentUser = FirebaseAuth.getInstance().getCurrentUser();
currentUserEmail = currentUser.getEmail();
databaseReference = FirebaseDatabase.getInstance().getReference("Users");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
currentUserType.clear();
FirebaseManager.isUserDoctor = false;
DataSnapshot allDoctors = dataSnapshot.child("Doctors");
DataSnapshot allPatients = dataSnapshot.child("Patients");
for (DataSnapshot ds : allDoctors.getChildren()) {
if (currentUserEmail.equals(Utils.decodeUserEmail(ds.getKey()))) {
currentUserType.add(ds.child("userType").getValue().toString());
} else {
for (DataSnapshot dsPacient : allPatients.getChildren()) {
if (currentUserEmail.equals(Utils.decodeUserEmail(dsPacient.getKey()))) {
currentUserType.add(dsPacient.child("userType").getValue().toString());
}
}
}
}
dataStatus.DataIsLoaded(currentUserType.get(0).toString());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
The interface
public interface DataStatus {
void DataIsLoaded(String userType);
}
The method's call in Main Menu
FirebaseManager.getInstance().getUserType(new DataStatus() {
#Override
public void DataIsLoaded(String userType) {
if ("doctor".equals(userType))
FirebaseManager.isUserDoctor = true;
else
FirebaseManager.isUserDoctor = false;
}
});
if (FirebaseManager.isUserDoctor)
setContentView(R.layout.activity_main_menu_doctor);
else
setContentView(R.layout.activity_main_menu);
So if anyone has any ideas about how to show the proper layout and allow functions based on user role/type please share. What I basically need is to retrieve the userType from the current email just in time to set a variable needed throughout the whole app in order to hide/show certain views.

Firebase "addListenerForSingleValueEvent" keeps getting old values that no longer is in Firebase database?

I keep getting the old values (which no longer is in the database) from my Firebase database. Here is how the database looks right now:
I am getting the info under friendlist. It used to be only one child there with key-value set soosk: true, but now it looks like in the photo. When using addListenerForSingleValueEvent() to my databaseRef, the friendlist retrieved only has soosk: true in it. Here is my code:
mFirebaseDatabaseReference = FirebaseDatabase
.getInstance()
.getReference(
"users/"+FirebaseAuth.getInstance().getCurrentUser().getUid()
);
mFirebaseDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
Log.d(TAG, user.getFriendlist().toString());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The method you need to use to have all the values updated is addValueEventListener(). Because you need to listen for more than one value this is the only way to achieve it and to use addListenerForSingleValueEvent().
The most important thing is to remove the listener in your onDestroy method like this:
yourReference.removeEventListener(valueEventListener);

Firebase Android: Which one is a better way to query in for selected node?

I'm developing a chat base app in Firebase Android. I got 2 ways to get the same result, but not able to detect which one is better in performance. Need help with following.
DB Structure:
Firebase -
- User
- user id
- name
- DOB
- userId
I need to fetch the user info for selected key. So there are 2 ways as follows:
Create Firebase database reference until userId and add an event listener to it:
database.child("Users").child(userCurrent.getUserId()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Create a Firebase database reference until Users node and then try to find the exact user by using equalTo query on key:
database.child("Users").orderByKey().equalTo(userCurrent.getUserId()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Will the second option fetch every user from User node and then query for equalTo?
You don't need to query if you can create exact reference to your user object. Querying is totally unnecessary in this case and of course worse performance.
The second option will not fetch every user on the Users node, it will just perform a query and return the user you are looking for.
Also if you don't want to listen for every change on the node I suggest using the addListenerForSingleValueEvent(), which will read the value one time only.

How to retrieve value from the highest/last level node using 'ChildEventListener' from Firebase?

I have several strings stored under specific reference: mReference.child(rID).child(userID2) which I want to retrieve using childEventListener as I am doing some task also when these string gets removed and that is only possible with onChildRemoved of ChildEventListener.
Here's what I have tried:
mReference.child(rID).child(userID2).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.d("dataHEre", dataSnapshot.getValue().toString());
}
}
The problem is that I'm unable to retrieve data using keys here as dataHEre is logging out:
D/dataHEre: 28.8419556
D/dataHEre: 78.779063
D/dataHEre: 3
D/dataHEre: Railway Colony
D/dataHEre: Sleep
D/dataHEre: 12:36 AM
D/dataHEre: Superman
which are values?
So, I want to know how can I retrieve data here using keys and using ChildEventListener and then assign the data retrieved to various strings?
I think that you are doing your query in the wrong way. onChildAdded method is retrieving you each child of a specific value (userID2 I suppose). If that is what you want, then just use a onValueEventListener() to retrieve the whole dataSnapshot of your userId2 node each time that it changes.
If you want to retrieve the data just once, you should use onSingleValueEventListener(). And OnChildEvent() is used to retrieve lists of data where you want to track each of the child individually. For example if you attach an OnChildEventListener to mReference.child(rID) you will get a OnChildAdded for each userId, what is pretty usefull like for example fill a RecyclerView or a ListView being able to update each item individually together with your Firebase Data.
If i'm not wrong what you want is just get updates of your userId2 reference, in that case attach a OnValueEventListener to that reference and you will get a call each time a value is modified, deleted, or added.
firebaseDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override public void onDataChange(DataSnapshot dataSnapshot) {
customPOJO customPOJO = dataSnapshot.getValue(YourCustomPOJO.class);
customPOJO.getName();
customPOJO.getEmail();
customPOJO.getfavoriteFood();
//and so on....
}
#Override public void onCancelled(DatabaseError databaseError) {
}
});

FireBase Android Need 1 value saved under a single user

I have the following data structure on firebase for the user MF0qeRA4p7djfjgXxqwFOck3m6p02. I want to get the value of item3 to populate a single field into the User interface on an Android App. I have been looking through samples on Stackoverflow, but all I have found are outdated and do not work with the current version of firebase. I'm new to firebase completely and this is my first app on android. I've got the oncreate user method to populate the users email address and add the 4 item fields, but retrieving the data I'm completely lost and I am not sure where to even begin.
-Users
---MF0qeRA4p7djfjgXxqwFOck3m6p02
------item1:"1"
------item2:"2"
------item3:"3"
------item4:"4"
According to what I can identify is, you are facing problem retrieving data from this reference. Here is the code:
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Users");
databaseReference.child("MF0qeRA4p7djfjgXxqwFOck3m6p02").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> map=(Map<String, Object>)dataSnapshot.getValue();
String item3=(String)map.get("item3");
display(item3);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Hope this helps.
You can create a custom model and inside you can insert elements. Something like this:
public class Item {
private List<Object> ojects;
}
There you can save instance of Item on database. In this case you have more controll. Other case is to use push() method, that will generate a new encoded key, something like this:
mDatabase.child("items").push().put(new Object());

Categories

Resources