Firebase data matchmaking - java

I'm making an app and I need to match data continuously in the activity. I'm using firebase for the database and I'm getting problem of getting my query right. I want to match the data in child(uid) to other data in different child(uid), in this case I'm still testing with only the date.
EDIT: I need to match the child of uid1 (for this case, the date) to ALL EXISTING dates available in the "Schedules". My bad.. the previous question stated was wrong where i said "matching the uid1 data to uid2 data"
Here is my code. I think my conditions aren't correct.
mInstance.getReference("Schedules").addValueEventListener(new ValueEventListener(){
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Schedule schedule = dataSnapshot.child(uid).getValue(Schedule.class);
for(DataSnapshot data: dataSnapshot.getChildren()) {
if (dataSnapshot.child(uid).child("date").exists() && dataSnapshot.child(uid).child("date").getChildrenCount()>= 2) {
test.setText("Found Match for " + schedule.date + "," + schedule.sport + ", and " + schedule.location);
} else {
test.setText(schedule.date + schedule.sport + schedule.location);
}
}
}
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}

Looking at your database cant a child("date") with children count greater than two.
If i may ask why are doing this?
There are two different approach to solve this problem
Get a list<> of all schedules from database and simply compare uid
or
If you already know the uid of the data you are looking for, get the data from database
More on firebase query
private Query queryGetSchedule;
private Query queryAllSchedule;
private ValueEventListener schedulesListener;
private ValueEventListener allSchedulesListener;
private FirebaseDatabase;
//Inside onCreate or class your are using
this.context = context; //pass in context
this.app = FirebaseApp.initializeApp(context);
this.id = myid;
if(firebaseDatabase == null) firebaseDatabase = FirebaseDatabase.getInstance();
queryGetSchedule = firebaseDatabase.getReference("Schedules").Child("key");
queryAllSchedule = firebaseDatabase.getReference().child("Schedules");
/**
* This will get you a single schedule
*/
public void getSingleSchedules()
{
if(schedulesListener == null)
{
schedulesListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
// MainActivity.userBook = snapshot.getValue(UserBook.class);
Schedule schedule = snapshot.getValue(Schedule.class);
callback.onUserCallback(userBook);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
}
};
}
queryGetSchedule.addListenerForSingleValueEvent(schedulesListener);
}
/**
*This will get you all your schedules in a list so you can easily compare
* Let assume you are passing in schedule of interest into this method
*/
public void getAllSchedulesListener(Schedule scheduleOfInterest) {
if(allSchedulesListener == null) {
allSchedulesListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
//Use this for list of objects passing in the type
GenericTypeIndicator<List<Schedule>> schedulesList =
new GenericTypeIndicator<List<Schedule>>() {
};
if(dataSnapshot.exists()) {
List<Schedule> mySchedulesList = dataSnapshot.getValue(schedulesList);
//after you get this full list of schedule you can compare with date as a string
for(Schedule schedule: mySchedulesList)
{
if(scheduleOfInterest.date.equals(schedule.date)
{
//found it
//do whatever here
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
}
};
}
queryAllSchedule.addListenerForSingleValueEvent(allSchedulesListener);
}

To solve this, simply use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidOneRef = rootRef.child("Schedules").child(uidOne);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String dateOne = ds.child("date").getValue(String.class);
Query uidTwoRef = rootRef.child("Schedules").orderByChild("date").equalTo(dateOne);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String dateTwo = ds.child("date").getValue(String.class);
Schedule schedule = dataSnapshot.getValue(Schedule.class);
if(dateOne.equals(dateTwo)) {
test.setText("Found Match for " + schedule.date + "," + schedule.sport + ", and " + schedule.location);
} else {
test.setText(schedule.date + schedule.sport + schedule.location);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
uidTwoRef.addListenerForSingleValueEvent(eventListener);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
uidOneRef.addListenerForSingleValueEvent(valueEventListener);
In which uidOne and uidTwo are the id of the users you want to check. I highly recommend you to store the data as a timestamp and not as a String, as it is explained here.

Related

How to ensure Completion handler for one Firebase lookup completes before another one does

I have the following Firebase DB node structure:
UserInGroup
--- GroupID
--- UserId : true/false
Users
--- UserId
--- Username : String
--- ...
GroupStatus
--- GroupId
--- UserId: true/false
I need to pull for the first node to get all the users in the Group
Then use that info to get the users account info details
Finally check to see the users status in the Group
I cannot figure a way to implement the completionhandler in Java/Android ? I have done so for iOS with completionhandlers.
Can anyone assist with helping me implement the solution in Java?
---- UPDATE ----
I have done the following:
// Create an interface to init all the callback functions
private interface AllUsersCallback {
void onSuccess(DataSnapshot dataSnapshot);
void onStart();
void onFailure();
}
private void readData(Query query, AllUsersActivity.AllUsersCallback listener) {
listener.onStart();
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
listener.onSuccess(dataSnapshot);
} else { // dataSnapshot doesn't exist
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
//
listener.onFailure();
}
});
}
And lastly the Activity view:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Init ArrayList
userList = new ArrayList<>();
userInGroupReference = mFirebaseDatabase.getReference("GroupUsers");
userInGroupQuery = userInGroupReference.child(groupID).orderByValue().equalTo(true);
// Completion Handler for Lookups
readData(userInGroupQuery, new AllUsersActivity.AllUsersCallback() {
#Override
public void onSuccess(DataSnapshot dataSnapshot) {
// Clear the List (remove dupes)
userList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
String userId = snapshot.getKey();
// Call function to set usernames to the users
setUsername(userId);
}
/*
THIS ALWAYS COMES OUT BLANK!? <--------
*/
for (int i = 0; i < userList.size(); i++) {
Log.e(TAG,"List element: " + userList.get(i).getUsername());
}
}
#Override
public void onStart() {
// When starting
Log.d("ONSTART", "Started");
}
#Override
public void onFailure() {
// If failed
Log.d("onFailure", "Failed");
}
});
}
and the function used to set the users username to the userList:
public void setUsername(String userId) {
userReference = mFirebaseDatabase.getReference("Users");
userQuery = userReference.child(userId).child("username");
// Add handle for listener
userQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
String username = dataSnapshot.getValue().toString();
AllUsers result = new AllUsers(username);
userList.add(result);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
These database calls are asynchronous - the callback code does not run immediately, it runs some time in the future when you actually get the data.
The easiest way to chain multiple dependent async queries is to put each query into its own function, and call it from the dependent query's callback. In your case, you could have multiple callbacks running at once, so as each one completes you can check for it to be done and check for them all to be done by comparing the size of the list with the number of queries launched.
For example:
private ArrayList<String> userList = new ArrayList<>();
private int numUsers = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// other setup stuff
startInitialQuery();
}
private void startInitialQuery() {
// make your initial query
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
userList.clear();
numUsers = 0; // dataSnapshot.getChildren().size();
// If the size() call above works, use that, otherwise
// you can count the number of children this way.
for(DataSnapshot snap : dataSnapshot.getChildren()) {
++numUsers;
}
for(DataSnapshot snap : dataSnapshot.getChildren()) {
String userId = snap.getKey();
readUser(userId);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
});
}
private void readUser(String userId) {
// make userQuery using "userId" input
userQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
String username = dataSnapshot.getValue().toString();
userList.add(username);
checkLoaded();
}
else {
--numUsers;
checkLoaded();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
--numUsers;
checkLoaded();
}
});
}
private void checkLoaded() {
if( userList.size() == numUsers ) {
// All done getting users! Show a toast, update a view, etc...
}
}
Alternately, if you switch to using Kotlin and coroutines you can write this as a pretty simple linear suspend function where you can actually make the different tasks wait.
A cleaner, but more invasive change, would be to move this all to a ViewModel that contains LiveData of each of these steps. As data is received, you post it to the LiveData and the UI can observe that and react accordingly (e.g update views, trigger the next call, etc).
Update
Here is an example showing how to do this with a ViewModel and LiveData
public class MainViewModel extends ViewModel {
private final MutableLiveData<List<String>> users = new MutableLiveData<>();
LiveData<List<String>> getUsers() {
return users;
}
private final ArrayList<String> userList = new ArrayList<>();
void startFetchingData() {
// build query
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
userList.clear();
for(DataSnapshot snap : dataSnapshot.getChildren()) {
String userId = snap.getKey();
readUser(userId);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
});
}
private void readUser(String userId) {
// build userQuery
userQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
String username = dataSnapshot.getValue().toString();
userList.add(username);
users.postValue(userList);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
});
}
}
and in the activity you set an observer for the LiveData that is notified any time the data changes.
model = new ViewModelProvider(this).get(MainViewModel.class);
final Observer<List<String>> userObserver = userList -> {
// Update the UI, or call something else
// this will get called every time the list of users is
// updated in the ViewModel
System.out.println("TEST: got data " + userList);
};
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
model.getUsers().observe(this, userObserver);
model.startFetchingData();

How to get value in Firebase

My database:
enter image description here
I got "Code". I try to get "ClassID" (Ex: Code=1235, I want a String ClassID= "12"):
Here my code:
private void checkCode(){
String userCode = inputCode.getText().toString().trim();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Assignment");
Query checkCode = reference.orderByChild("Code").equalTo(userCode);
checkCode.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
String classID; // I think here
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
How to do that?
If you want to search the database for all objects that have the "Code" property set to "1235" and then get the value of "classID", please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference assignmentRef = rootRef.child("Assignment");
Query codeQuery = assignmentRef.orderByChild("Code").equalTo("1235");
codeQuery.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
for (DataSnapshot ds : task.getResult().getChildren()) {
String classID = ds.child("classID").getValue(String.class);
Log.d("TAG", "ClassID: " + classID);
}
} else {
Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
The result in the logcat will be:
ClassID: 12
The exact value you are looking for. Remember that each time you query the database, you need to loop through the results using .getChildren() method, in order to get the results.

How to read child nodes without mentioning parent node in firebase database within android studio?

I am making an android app using the firebase Realtime database. My rules structure is given below:
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"Users": {
"$uid": {
".read": true,
// or ".read": "auth.uid != null" for only authenticated users
".write": "auth.uid == $uid"
}
}
}
}
It means that a user should be signed in as an authenticated user to write some data. But when it comes to read no sign in is required.
Now I need to ignore the uid of the user to give free access to other users( i.e. without signing in).
This is the java code I am using currently to read data.
final Intent k = getIntent();
final String school = Objects.requireNonNull(k.getExtras()).getString("School");
final Intent i = getIntent();
final String roll = Objects.requireNonNull(i.getExtras()).getString("Roll");
myRef = myfire.getReference("Users")
.child("GcZoeK7JIbNWVOog6ZjUPiBfxwn2")// **I have problem here.**
.child(school).child(roll);
myRef.child("basic").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String name = (String) dataSnapshot.child("fb01name").getValue().toString();
String number = (String) dataSnapshot.child("fb04roll").getValue().toString();
if(name == null){
Toast.makeText(getApplicationContext(),"Invalid",Toast.LENGTH_SHORT).show();
}
basic model = new basic(name,number);
tvName.setText(name);
tvRoll.setText(number);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
I could not decide what to write instead of the first child to read any data without signing in.
.child("GcZoeK7JIbNWVOog6ZjUPiBfxwn2")
Please guide me How to ignore this child? Any help will be appreciated.
EDIT
The advice "try to refrain from using deeply nested children" by #Abdullah Z Khan further provided me insight into the problem. I changed my codes as given below :
myfire = FirebaseDatabase.getInstance();
final Intent k = getIntent();
final String school = Objects.requireNonNull(k.getExtras()).getString("School");
final Intent i = getIntent();
final String roll = Objects.requireNonNull(i.getExtras()).getString("Roll");
//--------------------the trick----------------
if (school.equals("224613")){
tvSchool.setText("GcZoeK7JIbNWVOog6ZjUPiBfxwn2");
}else if (school.equals("224614")){
tvSchool.setText("uQx5jDVRp9PV3QpM2FBU6HPq5SJ3");
}
final String uid = tvSchool.getText().toString();
//---------------------------------------------------
myRef = myfire.getReference("Users").child(uid).child(roll);
myRef.child("basic").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String name = (String) dataSnapshot.child("fb01name").getValue().toString();
String number = (String) dataSnapshot.child("fb04roll").getValue().toString();
if(name == null){
Toast.makeText(getApplicationContext(),"Invalid",Toast.LENGTH_SHORT).show();
}
basic model = new basic(name,number);
tvName.setText(name);
tvRoll.setText(number);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Although this PLAN B has temporarily relieved me a bit yet the question is still unanswered.Beacuse I have to write the uid code of users each time they join the app( and have to update and publish the app again and again.A better solution is awaited.
EDIT: Added values in >>> marked lines for understanding
From what is given, this is your database structure:
{
"uid": {
"schoolId": {
"roll": {
}
}
}
}
Because it is so much nested (I'd suggest a different hierarchy altogether), there is no
easy way to access a child with an unknown parent as is. However, if you can change the database structure to this:
{
>>> "224614":"GcZoeK7JIbNWVOog6ZjUPiBfxwn2",
"schoolId2":"uid2",
>>> "GcZoeK7JIbNWVOog6ZjUPiBfxwn2": {
"224614": {
"roll": {
}
}
}
}
You'll get a uid lookup table. You can then use that to reach the node. Keep in mind this isn't a direct answer to what you asked, which is how to get a nested node(not value) without knowing the parent, but here you can dynamically access uids of whatever school is needed, assuming each school has exactly one parent.
After that, nest your listener:
myRef = myfire.getReference("Users");
myRef.child(school).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
String uid=dataSnapshot.getValue(String.class);
myRef.child(uid)// **I have problem here.**
.child(school).child(roll);
myRef.child("basic").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String name = (String) dataSnapshot.child("fb01name").getValue().toString();
String number = (String) dataSnapshot.child("fb04roll").getValue().toString();
if(name == null){
Toast.makeText(getApplicationContext(),"Invalid",Toast.LENGTH_SHORT).show();
}
basic model = new basic(name,number);
tvName.setText(name);
tvRoll.setText(number);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
In practice, try to refrain from using deeply nested children, rather use references to other nodes.
I hope this helps!!
how about this:
final Intent k = getIntent();
final String school = Objects.requireNonNull(k.getExtras()).getString("School");
final Intent i = getIntent();
final String roll = Objects.requireNonNull(i.getExtras()).getString("Roll");
myRef = myfire.getReference("Users")
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String name = (String) dataSnapshot.child(school).child(roll).child("basic").child("fb01name").getValue().toString();
String number = (String) dataSnapshot.child(school).child(roll).child("basic").child("fb04roll").getValue().toString();
if(name == null){
Toast.makeText(getApplicationContext(),"Invalid",Toast.LENGTH_SHORT).show();
}
basic model = new basic(name,number);
tvName.setText(name);
tvRoll.setText(number);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Well, I don't know if I understood your question, but if you are trying to read the children of all the nodes without specifying them, you can try to do something like the code below: (I didn't test it, I just changed your sample)
myRef = myfire.getReference("Users");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot keySnap : dataSnapshot.getChildren()) {
for (DataSnapshot schoolSnap : keySnap.getChildren()) {
for (DataSnapshot rollSnap : schoolSnap.getChildren()) {
String mRollSnap = rollSnap.getKey();
String name = mRollSnap.child("basic").child("fb01name").getValue().toString();
String number = (String) mRollSnap.child("basic").child("fb04roll").getValue().toString();
if(name == null){
Toast.makeText(getApplicationContext(),"Invalid",Toast.LENGTH_SHORT).show();
}
basic model = new basic(name,number);
tvName.setText(name);
tvRoll.setText(number);
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) { }
});

Unable to fetch data from Firebase (Android)

I am trying to fetch the data from the google firebase but every time i tried to fetch the data. "Else" case is running everytime. Tried to change if(dataSnapshot.exists()) but getting the same error. Please help to resolve it.
public void retrieveProfileInfo() {
currentUserID = mAuth.getUid();
key = rootRef.child("profiles").push().getKey();
rootRef.child("users-profiles").child(currentUserID).child(key)
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
try {
if ((dataSnapshot.child("name").getValue()) != null){
String retrieveName = dataSnapshot.child("name").getValue().toString();
String retrieveStatus = dataSnapshot.child("about").getValue().toString();
nameBox.setText(retrieveName);
aboutBox.setText(retrieveStatus);
} else {
Toast.makeText(UserProfileActivity.this, currentUserID+"else - retrieveProfileInfo()",
Toast.LENGTH_SHORT).show();
}
}catch (Exception e){
Log.i("retrieveProfileInfo : ", "error is : " + e);
Toast.makeText(UserProfileActivity.this, e+" : Error",
Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
You cant push a random key and read from it, you need to loop through children under users-profile/userID:
public void retrieveProfileInfo() {
//current user ID
currentUserID = mAuth.getUid();
ValueEventListener listener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds:dataSnapshot.getChildren()){
//get the values
String name = ds.child("name").getValue(String.class);
String about = ds.child("about").getValue(String.class);
String uid = ds.child("uid").getValue(String.class);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// log error
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
}
};
rootRef.child("users-profiles").child(currentUserID).addValueEventListener(listener);
}

Unable to get the value of child in firebase other than null

Not sure why, but with the code I have, I cannot seem to get the value of 'isOnline':
dolRef = DatabaseReference dolRef = FirebaseDatabase.getInstance().getReference("DriversOnline");
dolRef = dolRef.child("iosDriver");
dolRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String driverid = ds.getKey();
// get value of 'isOnline'
dolRef = dolRef.child(driverid);
Log.e(TAG, "dolRef: " + dolRef);
dolRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dss : dataSnapshot.getChildren()) {
String online = dss.child("isOnline").getValue(String.class);
Log.e(TAG, "Online: " + online);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Below is a part of my firebase db:
"DriversOnline" : {
"iosDriver" : {
"BruEGfToc8axIWJk1o01fxcwd8I2" : { // driverId
"isOnline" : "true",
"latitude" : 45.276,
"longitude" : -66.064
}
}
}
Any idea why I can't get the value of 'isOnline' other than null ?
I think you're nesting your listeners one level deeper than needed.
DatabaseReference iosRef = FirebaseDatabase.getInstance().getReference("DriversOnline/iosDriver");
iosRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot driverSnapshot: dataSnapshot.getChildren()) {
String driverid = driverSnapshot.getKey();
DataSnapshot isOnlineSnapshot = driverSnapshot.child("isOnline");
System.out.println(isOnlineSnapshot.getValue(String.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
Some things to note:
Reassigning one generically named dolRef variable 4 times in a block of code like this is a code-smell. It makes it much harder to follow what's going on, and to check if the variable points to the right location. Give each of them a name that clearly indicates what they point to, as I've done above.
There is no need to attach a second listener, as the value of isOnline is right in the driverSnapshot. You can just request the child snapshot with the right name, and then the value from that.
Don't ignore error, as that hides potential problems. At the very least throw them, as I've done above.
driverid = FirebaseDatabase.getInstance().getReference("driver");//If there is another driver table, the path must be two layers.
driverid.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Driver driver = dataSnapshot.getValue(Driver.class);//class model
dolRef = FirebaseDatabase.getInstance().getReference("DriversOnline/iosDriver").child(driver.getDriverID);
dolRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DriversOnline driversOnline= dataSnapshot.getValue(DriversOnline .class);//class model
log.d("driverid","isOnline :"+driversOnline.getisOnline)
//display -> isOnline : true
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Categories

Resources