how can i retrieve all hospitalNames from Hospitals where all userIds are unknown.
There are two main ways to navigate the DataSnapshot that you get in onDataChange.
If you know the name of a child node in a snapshot, you can use snapshot.child("hospitalData") to get that child snapshot from its parent.
If you don't know the name of the children in a snapshot, you can loop over snapshot.getChildren() to access each child snapshot.
By combining these, you can navigate any structure.
So you'll want to loop over the users with getChildren(), then access child("hospitalData") of each user, and get the values of each individual property with something like child("hospitalName").getValue(String.class).
How about this.
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("medicine/Hospitals");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
hospitalArrayList.clear();
for (DataSnapshot item : dataSnapshot.getChildren()) {
Hospital hospital = item.getValue(Hospital.class);
hospitalArrayList.add(hospital);
System.out.println(hospital);
}
dataRetrieved();
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
private void dataRetrieved() {
adapter.notifyDataSetChanged();
}
Hospital.java simple example
public class Hospital {
public HospitalData hospitalData;
public Hospital(HospitalData hospitalData) { }
public Hospital() { }
public static class HospitalData {
public String hospitalName;
public String hospitalAddress;
public HospitalData(String hospitalName, String hospitalAddress) { }
public HospitalData() { }
}
}
You can use this in adapter like this.
String name = hospitalArrayList.get(position).hospitalData.hospitalName;
You have to modify your structure.
Make a new Node name hospital and put userId in each hospital object
i.e
- medicine
..........
- medicineData
..........
- Patients
..........
- Pharmacies
..........
- hospitals
..........
Related
I stored datas from the database to an arrayList called nameList.
Within the function 'get_spinner_info', the values are successfully stored within the nameList.
However, there is no value for nameList outside of this function.
The error code is
" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 ".
I really need your help.
public class my_Item {
private Context context;
private FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference datebaseReference = firebaseDatabase.getReference();
ArrayList<String> nameList = new ArrayList<String>();
// Get the value from the database and put them in the 'nameList'.
//In this code, I can successfully check the value within the 'nameList'.
public void get_spinner_info(String brand, String item, String prod_key){
datebaseReference.child(brand).child(item).child(prod_key).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.child("myValue").getChildren()) {
String prod_name = ds.getValue().toString();
nameList.add(prod_name);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
// But the nameList is empty in this part.
public void callFunction(final String brand, final String item, final String product_name, final String product_key, final int product_Num) {
get_spinner_info(brand, item, product_key);
Log.d("Spinner namelist : ", nameList.get(0));
}
}
get_spinner_info method starts and ASYNCHRONOUS data loading (registers lsitener), thus onDataChange will get called after Log.d("Spinner nameList : ", nameList.get(0));
your data will be available only after onDataChange call, which may take some time. get_spinner_info just starts loading your data, doesn't means that all data will be available just after method call ends
put this on the end of onDataChange (after current for loop) to check your items available/present in array
for (String name : nameList) Log.d("Spinner", "name: " + name);
Synchronization problem cause this kind of error
if you already have data do this
create interface class
public interface DataCallback {
public void reciveData(ArrayList<String> nameList ,boolean isOk);
}
In your class my_Item call the interface like this
public void get_spinner_info(String brand,String item,String prod_key,DataCallback callback){
datebaseReference.child(brand).child(item).child(prod_key).addListenerForSingleValueEvent(new ValueEventListener(){
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot){
for(DataSnapshot ds:dataSnapshot.child("myValue").getChildren()){
String prod_name=ds.getValue().toString();
nameList.add(prod_name);
}
// here you should check if the result available or NOT to prevent null exceptions
if(nameList.size()>0){
callback.reciveData(nameList,true);// true and false used to check data if available or null
}
else{
callback.reciveData(nameList,false);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError){
}
});
}
Now when you call get_spinner_info you need the callback Like this
get_spinner_info(brand, item, product_key,new DataCallback() {
#Override
public void callback(ArrayList<String> nameList, boolean isOk) {
if (isOk){
/// you have all data recived
Log.d("Spinner namelist : ", nameList.get(0));
}else {
// no data available
Log.i("TAG", "callback: No Data Available");
}
}
}););
I'm trying to set up an order placing system.
Once the user is verified via email, it can create/update/delete order.
Order is saved into Firebase Real-time Database and users are saved in Authentication.
I would like to allow user to only see/edit orders that were placed by this specific user. Basically make use of UserUID from Authentication section.
public class FirebaseDatabaseHelper {
private FirebaseDatabase mDatabase;
private DatabaseReference mReferenceOrders;
private List<Order> orders = new ArrayList<>();
public interface DataStatus{
void DataIsLoaded(List<Order> orders, List<String> keys);
void DataIsInserted();
void DataIsUpdated();
void DataIsDeleted();
}
//Initialize Database object
public FirebaseDatabaseHelper() {
mDatabase = FirebaseDatabase.getInstance();
mReferenceOrders = ((FirebaseDatabase) mDatabase).getReference("order");
}
public void readOrders(final DataStatus dataStatus){
mReferenceOrders.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
orders.clear();
List<String> keys = new ArrayList<>();
for(DataSnapshot keyNode : dataSnapshot.getChildren()) {
keys.add(keyNode.getKey());
Order order = keyNode.getValue(Order.class);
orders.add(order);
}
dataStatus.DataIsLoaded(orders,keys);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
public void addOrder(Order order, final DataStatus dataStatus) {
String key = mReferenceOrders.push().getKey();
mReferenceOrders.child(key).setValue(order).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dataStatus.DataIsInserted();
}
});
}
// Update and Delete methods
public void updateOrder(String key, Order order, final DataStatus dataStatus){
mReferenceOrders.child(key).setValue(order).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dataStatus.DataIsUpdated();
}
});
}
public void deleteOrder(String key, final DataStatus dataStatus){
mReferenceOrders.child(key).setValue(null).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dataStatus.DataIsDeleted();
}
});
}
}
Here's what I was thinking:
When a user creates a new order then a UserUID is added to a database and nested inside 'order' so now each order can be assigned to a user that created it.
Now the next step would be to display this order to a user that created it but only if cust_id (in order) matches UserUID of a logged in user. Would that be a good approach?
Yes, it is a good approach, now you need to add to your Firebase Realtime Database now branch with your users data based on userUID, like this:
Thanks to this you will be able to connect your users with their orders data and besides you can save here more specific user data like "how many orders user create", "how many orders are active" etc.
I have added a user_id to an 'order' in the Firebase database so each order can be assigned to its user.
I got the parameter for user_id by fetching a UserUID from an Authentication section of Firebase when a new user is logged/signed in.
Screenshot of UserUID in Authentication section of Firebase
I got this value in my code by adding the following:
private FirebaseAuth mAuth;
order.setUser_id(mAuth.getCurrentUser().getUid());
Once I got the user_id assigned to each order I've created a following if statement which is implemented in my readOrders function which you can see in my original post above:
public void readOrders(final DataStatus dataStatus){
mReferenceOrders.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
orders.clear();
List<String> keys = new ArrayList<>();
for(DataSnapshot keyNode : dataSnapshot.getChildren()) {
keys.add(keyNode.getKey());
Order order = keyNode.getValue(Order.class);
**if (order.getUser_id().equals(mAuth.getUid())) {
Log.d("FirebaseDatabaseHelper", "match");
orders.add(order);
}else {
Log.d("FirebaseDatabaseHelper", "error");
}**
}
dataStatus.DataIsLoaded(orders,keys);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
So basically now when the new user logs in, there will be nothing to show because the user_id won't match with any of the user_id's inside Order database.
I'm not sure how efficient this method will be when more users/orders will be added so I'll have to do some testing.
Please advise if this is the best approach!
I am working on app where I want to show the data only of the users whose contact numbers are saved in the phone. So, I retrieved a list of contact numbers contactList. Now, I want to get all the contactList user's post from Firebase. Is there any way I can ask the Firebase for only those nodes in my contactList. One Way is to retrieve all users and then get relevant users from that (like I did below). Is there any better way to do so ?
Users: {
7828272892 : {
name: xyz,
gender: male,
phoneNo: 7828272892
Posts: {
SomeKey1: {
content: "This is post 1", Var2: "kkk"} }},
7924272894 : {name: abc, gender: male, phoneNo: 7924272894}
}
Code:
databaseReference.child("Users").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
List<Post> allItems = new ArrayList<Post>();
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
if (contactList.contains(postSnapshot.child("phoneNo").getValue())) {
// retrieve posts
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Is there any way I can ask the firebase for only those nodes in my contactList?
Yes, the way in which you already do this.
Is there any better way to do so?
The way in which you do this is a common practice used in Firebase. You query the database and check is the data already exists in the list, in your case in the contactList. If the list contains that phoneNo then you can retrieve the posts.
Try this code to read multiple nodes data..
mFirebaseInstance = FirebaseDatabase.getInstance();
mDatabase = mFirebaseInstance.getReference("usersDb/UserTable");
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mUserList.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
User user = dataSnapshot1.getValue(User.class);
mUserList.add(user); // add all data into list.
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
How Can I get ArrayList of Java Objects of all Childs from Firebase using updated firebase commands, currently I am using below approach but not able to get the list.
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
if(dataSnapshot!=null){
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
UserDataClass post = postSnapshot.getValue(UserDataClass.class);
members.add(post);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
}
};
mDatabaseRef.addValueEventListener(postListener);
below is datasnapshot which is returning from firebase but I am not able to get the desired result out of it.
DataSnapshot { key = 12345, value = {Members={00000000={phoneNo=00000000, longitude=73.0703307, latitude=33.6396975, password=qwertyuiop, CName=00000000, admin=true, name=Anwar Kamal}, 03028084374={phoneNo=03028084374, longitude=73.0701292, latitude=33.6397129, password=qwerty, CName=00000000, admin=false, name=Nehal Khan}, 03028084516={phoneNo=03028084516, longitude=73.0702659, latitude=33.6397622, password=qwerty, CName=03035356317, admin=false, name=Jamal Khan}}} }
all i want is list of all members
and my java object is
public class UserDataClass {
public double latitude;
public double longitude;
public String Name="";
public String password="";
public String phoneNo="";
public String CircleName="";
public boolean isAdmin=false;
}
The ValueEventListener has another purpose.
You should use ChildEventListener and also dataSnapshop.getValue() to implement what you want, for example:
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
UserDataClass post = postSnapshot.getValue(UserDataClass.class);
members.add(post);
}
//...
Note:
You should use the listener with the current firebase_referance to the Users table. Hence you should replace
mDatabaseRef.addValueEventListener(postListener);
with
mDatabaseRef.child("Members").addChildEventListener(childEventListener);
notice that your full path of the Members table is colored and i couldn't figure the path.
You can find the whole documentation here
good luck
I am writing an Android app and I am trying to retrieve an object of the class User.java by ID from its Firebase pertinent table. I would like to know how to get it from Java side, as long as I tried the examples stated in Firebase Official docs but none of them is working for me.
Taking this SO question as example, I want a method with the following interface:
public User readUser(String userId);
In other words, I want to execute:
readUser(-lnnROTBVv6FznK81k3n)
and retrieve the associated User object
Thanks
--------------------------------------------------------------EDIT--------------------------------------------------------------:
I managed to get the value with this code:
public void retrieveUser(final String email){
firebaseUsersRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
if(messageSnapshot.getKey().equals(Email.encodeID(email))){
retrievedUser = messageSnapshot.getValue(User.class);
break;
}
}
}
#Override
public void onCancelled(FirebaseError firebaseError) { }
});
}
Please not retrievedUser is a class attribute, thus a field. I am accessing that field from the code, but even I see it takes the value on the debugger, it is being null on the calling code.
Any hint? CanĀ“t I just return it in the method itself, so it would be?:
public User retrieveUser(final String email);
Thanks
so here is the soultion, I didn't put it in a method though.
final String uid = "your Uid here";
// Get a reference to users
Firebase ref = new Firebase(Constants.FIREBASE_URL_USERS);
// Attach an listener to read our users
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot user: snapshot.getChildren()) {
//this is all you need to get a specific user by Uid
if (user.getKey().equals(uid)){
wantedUser = user.getValue(User.class);
}
//**********************************************
}
Log.i(TAG, "onDataChange: " + wantedUser.getName());
}
#Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println("The read failed: " + firebaseError.getMessage());
}
});