Can't get the return value from a method that retrieves data from Firebase Realtime database to use it in...
This question already has an answer here:
How to return DataSnapshot value as a result of a method?
3 answers
I'm quite new to Firebase Realtime database. I'm working on an android app which requires data to be retrieved from Firebase Realtime DB. I've been able to retrieve data using the Firebase listener methods in most occasions but on one occasion, I've found it unable to get a value in the way that I want (I think because of the asynchronous nature).
SCENARIO:-
I have a data structure in Firebase Realtime Database as follows:
For rating:

For users:

I have a separate java class (Suggest.java) that has one simple method to get a list of users (not shown here since it is the basic implementation) and the method defined below to retrieve data from the above ratings node to a list:
public List<String> getMyUnratedPosts(final String currentUserId){
final List<String> currentUserUnratedPosts = new ArrayList<>();
DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adRat").child(currentUserId);
DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
AdRat adr = snapshot.getValue(AdRat.class);
int vr = adr.getViewRating();
if(vr < 1) {
currentUserUnratedPosts.add(adr.getAdId());
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return currentUserUnratedPosts;
}
The AdRat class defined above is just a class with attributes (and getters and setters) which matches the database node given above.
I'm creating an instance of this class (Suggest.java) in the onCreate() method of my activity. Then first I'm calling a method in which I'm simply getting a list of users (very similar to above method in which I get the ratings). Then the next line of code in my activity I use a for loop to get each user from the list I got and use that userId for the method shown above. For example, it would be as follows:
Suggest sj = new Suggest();
List<String> users = sj.getUsers();
for (final String mUser: users) {
//Just trying to use the user from above here
List<String> myUnratedItems = sj.getMyUnratedPosts(mUser);
Log.d(TAG, "list contains : " + myUnratedItems.toString());
}
PROBLEM :-
I do not get the intended result from the code when I run this. When I debug it, I will get null for the list of users. I think since the firebase methods are asynchronous they do not give the result exactly at the next line of code (that is the place where I need it) but gives the result a bit later (but then the program has run over the line of code in which I need that data).
MY OVERALL NECESSITY : -
Get the list of users to use it in the next line of code (for the next method).
I've gone through several questions in Stackoverflow in regard to this, but couldn't find an exact answer for this.
Please kindly explain as to why this happens and any workaround for this....
P.S. : - I'm new to stackoverflow, so please bear with me any mistakes done in composing the question. Thanks.
java
marked as duplicate by Alex Mamo
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 12:11
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
This question already has an answer here:
How to return DataSnapshot value as a result of a method?
3 answers
I'm quite new to Firebase Realtime database. I'm working on an android app which requires data to be retrieved from Firebase Realtime DB. I've been able to retrieve data using the Firebase listener methods in most occasions but on one occasion, I've found it unable to get a value in the way that I want (I think because of the asynchronous nature).
SCENARIO:-
I have a data structure in Firebase Realtime Database as follows:
For rating:

For users:

I have a separate java class (Suggest.java) that has one simple method to get a list of users (not shown here since it is the basic implementation) and the method defined below to retrieve data from the above ratings node to a list:
public List<String> getMyUnratedPosts(final String currentUserId){
final List<String> currentUserUnratedPosts = new ArrayList<>();
DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adRat").child(currentUserId);
DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
AdRat adr = snapshot.getValue(AdRat.class);
int vr = adr.getViewRating();
if(vr < 1) {
currentUserUnratedPosts.add(adr.getAdId());
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return currentUserUnratedPosts;
}
The AdRat class defined above is just a class with attributes (and getters and setters) which matches the database node given above.
I'm creating an instance of this class (Suggest.java) in the onCreate() method of my activity. Then first I'm calling a method in which I'm simply getting a list of users (very similar to above method in which I get the ratings). Then the next line of code in my activity I use a for loop to get each user from the list I got and use that userId for the method shown above. For example, it would be as follows:
Suggest sj = new Suggest();
List<String> users = sj.getUsers();
for (final String mUser: users) {
//Just trying to use the user from above here
List<String> myUnratedItems = sj.getMyUnratedPosts(mUser);
Log.d(TAG, "list contains : " + myUnratedItems.toString());
}
PROBLEM :-
I do not get the intended result from the code when I run this. When I debug it, I will get null for the list of users. I think since the firebase methods are asynchronous they do not give the result exactly at the next line of code (that is the place where I need it) but gives the result a bit later (but then the program has run over the line of code in which I need that data).
MY OVERALL NECESSITY : -
Get the list of users to use it in the next line of code (for the next method).
I've gone through several questions in Stackoverflow in regard to this, but couldn't find an exact answer for this.
Please kindly explain as to why this happens and any workaround for this....
P.S. : - I'm new to stackoverflow, so please bear with me any mistakes done in composing the question. Thanks.
java
marked as duplicate by Alex Mamo
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 12:11
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
Firebase requests are asynchronous, so your return currentUserUnratedPosts; will be alwayys 0 or null because you are trying to return something that has not been loaded yet.
– Gastón Saillén
Nov 14 '18 at 5:32
Please check the duplicate to see why do you have this behaviour and how can you solve this using a custom callback.
– Alex Mamo
Nov 14 '18 at 12:11
Hey @VandyWhite do mark the answer as correct by clicking the V type tick mark button next to the answer, and vote it up by clicking the up arrow button next to the answer, this helps people with similar question on Stack Overflow and I'd also appreciate that. Cheers!
– PradyumanDixit
Dec 26 '18 at 4:18
add a comment |
This question already has an answer here:
How to return DataSnapshot value as a result of a method?
3 answers
I'm quite new to Firebase Realtime database. I'm working on an android app which requires data to be retrieved from Firebase Realtime DB. I've been able to retrieve data using the Firebase listener methods in most occasions but on one occasion, I've found it unable to get a value in the way that I want (I think because of the asynchronous nature).
SCENARIO:-
I have a data structure in Firebase Realtime Database as follows:
For rating:

For users:

I have a separate java class (Suggest.java) that has one simple method to get a list of users (not shown here since it is the basic implementation) and the method defined below to retrieve data from the above ratings node to a list:
public List<String> getMyUnratedPosts(final String currentUserId){
final List<String> currentUserUnratedPosts = new ArrayList<>();
DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adRat").child(currentUserId);
DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
AdRat adr = snapshot.getValue(AdRat.class);
int vr = adr.getViewRating();
if(vr < 1) {
currentUserUnratedPosts.add(adr.getAdId());
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return currentUserUnratedPosts;
}
The AdRat class defined above is just a class with attributes (and getters and setters) which matches the database node given above.
I'm creating an instance of this class (Suggest.java) in the onCreate() method of my activity. Then first I'm calling a method in which I'm simply getting a list of users (very similar to above method in which I get the ratings). Then the next line of code in my activity I use a for loop to get each user from the list I got and use that userId for the method shown above. For example, it would be as follows:
Suggest sj = new Suggest();
List<String> users = sj.getUsers();
for (final String mUser: users) {
//Just trying to use the user from above here
List<String> myUnratedItems = sj.getMyUnratedPosts(mUser);
Log.d(TAG, "list contains : " + myUnratedItems.toString());
}
PROBLEM :-
I do not get the intended result from the code when I run this. When I debug it, I will get null for the list of users. I think since the firebase methods are asynchronous they do not give the result exactly at the next line of code (that is the place where I need it) but gives the result a bit later (but then the program has run over the line of code in which I need that data).
MY OVERALL NECESSITY : -
Get the list of users to use it in the next line of code (for the next method).
I've gone through several questions in Stackoverflow in regard to this, but couldn't find an exact answer for this.
Please kindly explain as to why this happens and any workaround for this....
P.S. : - I'm new to stackoverflow, so please bear with me any mistakes done in composing the question. Thanks.
java
This question already has an answer here:
How to return DataSnapshot value as a result of a method?
3 answers
I'm quite new to Firebase Realtime database. I'm working on an android app which requires data to be retrieved from Firebase Realtime DB. I've been able to retrieve data using the Firebase listener methods in most occasions but on one occasion, I've found it unable to get a value in the way that I want (I think because of the asynchronous nature).
SCENARIO:-
I have a data structure in Firebase Realtime Database as follows:
For rating:

For users:

I have a separate java class (Suggest.java) that has one simple method to get a list of users (not shown here since it is the basic implementation) and the method defined below to retrieve data from the above ratings node to a list:
public List<String> getMyUnratedPosts(final String currentUserId){
final List<String> currentUserUnratedPosts = new ArrayList<>();
DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adRat").child(currentUserId);
DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
AdRat adr = snapshot.getValue(AdRat.class);
int vr = adr.getViewRating();
if(vr < 1) {
currentUserUnratedPosts.add(adr.getAdId());
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return currentUserUnratedPosts;
}
The AdRat class defined above is just a class with attributes (and getters and setters) which matches the database node given above.
I'm creating an instance of this class (Suggest.java) in the onCreate() method of my activity. Then first I'm calling a method in which I'm simply getting a list of users (very similar to above method in which I get the ratings). Then the next line of code in my activity I use a for loop to get each user from the list I got and use that userId for the method shown above. For example, it would be as follows:
Suggest sj = new Suggest();
List<String> users = sj.getUsers();
for (final String mUser: users) {
//Just trying to use the user from above here
List<String> myUnratedItems = sj.getMyUnratedPosts(mUser);
Log.d(TAG, "list contains : " + myUnratedItems.toString());
}
PROBLEM :-
I do not get the intended result from the code when I run this. When I debug it, I will get null for the list of users. I think since the firebase methods are asynchronous they do not give the result exactly at the next line of code (that is the place where I need it) but gives the result a bit later (but then the program has run over the line of code in which I need that data).
MY OVERALL NECESSITY : -
Get the list of users to use it in the next line of code (for the next method).
I've gone through several questions in Stackoverflow in regard to this, but couldn't find an exact answer for this.
Please kindly explain as to why this happens and any workaround for this....
P.S. : - I'm new to stackoverflow, so please bear with me any mistakes done in composing the question. Thanks.
This question already has an answer here:
How to return DataSnapshot value as a result of a method?
3 answers
java
java
edited Nov 14 '18 at 6:23
PradyumanDixit
2,1812819
2,1812819
asked Nov 14 '18 at 4:29
Vandy WhiteVandy White
112
112
marked as duplicate by Alex Mamo
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 12:11
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by Alex Mamo
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 12:11
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
Firebase requests are asynchronous, so your return currentUserUnratedPosts; will be alwayys 0 or null because you are trying to return something that has not been loaded yet.
– Gastón Saillén
Nov 14 '18 at 5:32
Please check the duplicate to see why do you have this behaviour and how can you solve this using a custom callback.
– Alex Mamo
Nov 14 '18 at 12:11
Hey @VandyWhite do mark the answer as correct by clicking the V type tick mark button next to the answer, and vote it up by clicking the up arrow button next to the answer, this helps people with similar question on Stack Overflow and I'd also appreciate that. Cheers!
– PradyumanDixit
Dec 26 '18 at 4:18
add a comment |
Firebase requests are asynchronous, so your return currentUserUnratedPosts; will be alwayys 0 or null because you are trying to return something that has not been loaded yet.
– Gastón Saillén
Nov 14 '18 at 5:32
Please check the duplicate to see why do you have this behaviour and how can you solve this using a custom callback.
– Alex Mamo
Nov 14 '18 at 12:11
Hey @VandyWhite do mark the answer as correct by clicking the V type tick mark button next to the answer, and vote it up by clicking the up arrow button next to the answer, this helps people with similar question on Stack Overflow and I'd also appreciate that. Cheers!
– PradyumanDixit
Dec 26 '18 at 4:18
Firebase requests are asynchronous, so your return currentUserUnratedPosts; will be alwayys 0 or null because you are trying to return something that has not been loaded yet.
– Gastón Saillén
Nov 14 '18 at 5:32
Firebase requests are asynchronous, so your return currentUserUnratedPosts; will be alwayys 0 or null because you are trying to return something that has not been loaded yet.
– Gastón Saillén
Nov 14 '18 at 5:32
Please check the duplicate to see why do you have this behaviour and how can you solve this using a custom callback.
– Alex Mamo
Nov 14 '18 at 12:11
Please check the duplicate to see why do you have this behaviour and how can you solve this using a custom callback.
– Alex Mamo
Nov 14 '18 at 12:11
Hey @VandyWhite do mark the answer as correct by clicking the V type tick mark button next to the answer, and vote it up by clicking the up arrow button next to the answer, this helps people with similar question on Stack Overflow and I'd also appreciate that. Cheers!
– PradyumanDixit
Dec 26 '18 at 4:18
Hey @VandyWhite do mark the answer as correct by clicking the V type tick mark button next to the answer, and vote it up by clicking the up arrow button next to the answer, this helps people with similar question on Stack Overflow and I'd also appreciate that. Cheers!
– PradyumanDixit
Dec 26 '18 at 4:18
add a comment |
2 Answers
2
active
oldest
votes
Indeed, the eventListeners and calls to Firebase have asynchronous behaviour and thus you have correctly understood your problem.
Unfortunately the solution I have(which almost certainly works) is that you may have to change your approach because of this.
So you should go for an event driven approach. Hence, instead of "wait for the data to come and and then do my thing", you should "when the data comes in, do my thing".
Meaning according to your problem, firs you should retrieve the list of users from the Firebase as you have correctly done in the onDataChange() of valueEventListener, and beneath it, do your thing which you intend to do.
The problem is that since Firebase has asynchronous calls, your data gets printed before it can retrieved, which obviously would be null if you haven't initialised it to something else. So all further operations that you do, occur on null.
So it would be better for you to execute your method or code inside the valueEventListener itself.
Something like this in your given code:
public List<String> getMyUnratedPosts(final String currentUserId){
final List<String> currentUserUnratedPosts = new ArrayList<>();
DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adRat").child(currentUserId);
DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
AdRat adr = snapshot.getValue(AdRat.class);
int vr = adr.getViewRating();
if(vr < 1) {
currentUserUnratedPosts.add(adr.getAdId());
}
}
// do your thing right here
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return currentUserUnratedPosts;
}
Other than that, one more approach I found, when I searched though, is Task.await(). But, I won't be counting on it.
You may read more about that here:
StackOverflow Question
StackOverflow Answer
add a comment |
You're exactly right in that it is caused by the asynchronicity of the Firebase calls. The kind of system you'll most likely want to employ is one in which you "subscribe" to know when calls have completed. You can use a callback function, or some other method, such as adding a field/piece of data to a list, and having another data structure periodically check the list for updates, in order to know when the async call has completed.
Your flow will probably be something like this:
- "subscribe" to the asynchronous data structure
- tell asynchronous data structure to execute
- on completion of the asynchronous call, perform some action.
I'd recommend looking at the following link on Asynchronous callbacks in Java from Geeksforgeeks: https://www.geeksforgeeks.org/asynchronous-synchronous-callbacks-java/
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Indeed, the eventListeners and calls to Firebase have asynchronous behaviour and thus you have correctly understood your problem.
Unfortunately the solution I have(which almost certainly works) is that you may have to change your approach because of this.
So you should go for an event driven approach. Hence, instead of "wait for the data to come and and then do my thing", you should "when the data comes in, do my thing".
Meaning according to your problem, firs you should retrieve the list of users from the Firebase as you have correctly done in the onDataChange() of valueEventListener, and beneath it, do your thing which you intend to do.
The problem is that since Firebase has asynchronous calls, your data gets printed before it can retrieved, which obviously would be null if you haven't initialised it to something else. So all further operations that you do, occur on null.
So it would be better for you to execute your method or code inside the valueEventListener itself.
Something like this in your given code:
public List<String> getMyUnratedPosts(final String currentUserId){
final List<String> currentUserUnratedPosts = new ArrayList<>();
DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adRat").child(currentUserId);
DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
AdRat adr = snapshot.getValue(AdRat.class);
int vr = adr.getViewRating();
if(vr < 1) {
currentUserUnratedPosts.add(adr.getAdId());
}
}
// do your thing right here
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return currentUserUnratedPosts;
}
Other than that, one more approach I found, when I searched though, is Task.await(). But, I won't be counting on it.
You may read more about that here:
StackOverflow Question
StackOverflow Answer
add a comment |
Indeed, the eventListeners and calls to Firebase have asynchronous behaviour and thus you have correctly understood your problem.
Unfortunately the solution I have(which almost certainly works) is that you may have to change your approach because of this.
So you should go for an event driven approach. Hence, instead of "wait for the data to come and and then do my thing", you should "when the data comes in, do my thing".
Meaning according to your problem, firs you should retrieve the list of users from the Firebase as you have correctly done in the onDataChange() of valueEventListener, and beneath it, do your thing which you intend to do.
The problem is that since Firebase has asynchronous calls, your data gets printed before it can retrieved, which obviously would be null if you haven't initialised it to something else. So all further operations that you do, occur on null.
So it would be better for you to execute your method or code inside the valueEventListener itself.
Something like this in your given code:
public List<String> getMyUnratedPosts(final String currentUserId){
final List<String> currentUserUnratedPosts = new ArrayList<>();
DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adRat").child(currentUserId);
DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
AdRat adr = snapshot.getValue(AdRat.class);
int vr = adr.getViewRating();
if(vr < 1) {
currentUserUnratedPosts.add(adr.getAdId());
}
}
// do your thing right here
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return currentUserUnratedPosts;
}
Other than that, one more approach I found, when I searched though, is Task.await(). But, I won't be counting on it.
You may read more about that here:
StackOverflow Question
StackOverflow Answer
add a comment |
Indeed, the eventListeners and calls to Firebase have asynchronous behaviour and thus you have correctly understood your problem.
Unfortunately the solution I have(which almost certainly works) is that you may have to change your approach because of this.
So you should go for an event driven approach. Hence, instead of "wait for the data to come and and then do my thing", you should "when the data comes in, do my thing".
Meaning according to your problem, firs you should retrieve the list of users from the Firebase as you have correctly done in the onDataChange() of valueEventListener, and beneath it, do your thing which you intend to do.
The problem is that since Firebase has asynchronous calls, your data gets printed before it can retrieved, which obviously would be null if you haven't initialised it to something else. So all further operations that you do, occur on null.
So it would be better for you to execute your method or code inside the valueEventListener itself.
Something like this in your given code:
public List<String> getMyUnratedPosts(final String currentUserId){
final List<String> currentUserUnratedPosts = new ArrayList<>();
DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adRat").child(currentUserId);
DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
AdRat adr = snapshot.getValue(AdRat.class);
int vr = adr.getViewRating();
if(vr < 1) {
currentUserUnratedPosts.add(adr.getAdId());
}
}
// do your thing right here
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return currentUserUnratedPosts;
}
Other than that, one more approach I found, when I searched though, is Task.await(). But, I won't be counting on it.
You may read more about that here:
StackOverflow Question
StackOverflow Answer
Indeed, the eventListeners and calls to Firebase have asynchronous behaviour and thus you have correctly understood your problem.
Unfortunately the solution I have(which almost certainly works) is that you may have to change your approach because of this.
So you should go for an event driven approach. Hence, instead of "wait for the data to come and and then do my thing", you should "when the data comes in, do my thing".
Meaning according to your problem, firs you should retrieve the list of users from the Firebase as you have correctly done in the onDataChange() of valueEventListener, and beneath it, do your thing which you intend to do.
The problem is that since Firebase has asynchronous calls, your data gets printed before it can retrieved, which obviously would be null if you haven't initialised it to something else. So all further operations that you do, occur on null.
So it would be better for you to execute your method or code inside the valueEventListener itself.
Something like this in your given code:
public List<String> getMyUnratedPosts(final String currentUserId){
final List<String> currentUserUnratedPosts = new ArrayList<>();
DBRCurrentUnratedList = FirebaseDatabase.getInstance().getReference().child("adRat").child(currentUserId);
DBRCurrentUnratedList.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
AdRat adr = snapshot.getValue(AdRat.class);
int vr = adr.getViewRating();
if(vr < 1) {
currentUserUnratedPosts.add(adr.getAdId());
}
}
// do your thing right here
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return currentUserUnratedPosts;
}
Other than that, one more approach I found, when I searched though, is Task.await(). But, I won't be counting on it.
You may read more about that here:
StackOverflow Question
StackOverflow Answer
answered Nov 14 '18 at 4:56
PradyumanDixitPradyumanDixit
2,1812819
2,1812819
add a comment |
add a comment |
You're exactly right in that it is caused by the asynchronicity of the Firebase calls. The kind of system you'll most likely want to employ is one in which you "subscribe" to know when calls have completed. You can use a callback function, or some other method, such as adding a field/piece of data to a list, and having another data structure periodically check the list for updates, in order to know when the async call has completed.
Your flow will probably be something like this:
- "subscribe" to the asynchronous data structure
- tell asynchronous data structure to execute
- on completion of the asynchronous call, perform some action.
I'd recommend looking at the following link on Asynchronous callbacks in Java from Geeksforgeeks: https://www.geeksforgeeks.org/asynchronous-synchronous-callbacks-java/
add a comment |
You're exactly right in that it is caused by the asynchronicity of the Firebase calls. The kind of system you'll most likely want to employ is one in which you "subscribe" to know when calls have completed. You can use a callback function, or some other method, such as adding a field/piece of data to a list, and having another data structure periodically check the list for updates, in order to know when the async call has completed.
Your flow will probably be something like this:
- "subscribe" to the asynchronous data structure
- tell asynchronous data structure to execute
- on completion of the asynchronous call, perform some action.
I'd recommend looking at the following link on Asynchronous callbacks in Java from Geeksforgeeks: https://www.geeksforgeeks.org/asynchronous-synchronous-callbacks-java/
add a comment |
You're exactly right in that it is caused by the asynchronicity of the Firebase calls. The kind of system you'll most likely want to employ is one in which you "subscribe" to know when calls have completed. You can use a callback function, or some other method, such as adding a field/piece of data to a list, and having another data structure periodically check the list for updates, in order to know when the async call has completed.
Your flow will probably be something like this:
- "subscribe" to the asynchronous data structure
- tell asynchronous data structure to execute
- on completion of the asynchronous call, perform some action.
I'd recommend looking at the following link on Asynchronous callbacks in Java from Geeksforgeeks: https://www.geeksforgeeks.org/asynchronous-synchronous-callbacks-java/
You're exactly right in that it is caused by the asynchronicity of the Firebase calls. The kind of system you'll most likely want to employ is one in which you "subscribe" to know when calls have completed. You can use a callback function, or some other method, such as adding a field/piece of data to a list, and having another data structure periodically check the list for updates, in order to know when the async call has completed.
Your flow will probably be something like this:
- "subscribe" to the asynchronous data structure
- tell asynchronous data structure to execute
- on completion of the asynchronous call, perform some action.
I'd recommend looking at the following link on Asynchronous callbacks in Java from Geeksforgeeks: https://www.geeksforgeeks.org/asynchronous-synchronous-callbacks-java/
answered Nov 14 '18 at 4:58
loganrussell48loganrussell48
84310
84310
add a comment |
add a comment |
Firebase requests are asynchronous, so your return currentUserUnratedPosts; will be alwayys 0 or null because you are trying to return something that has not been loaded yet.
– Gastón Saillén
Nov 14 '18 at 5:32
Please check the duplicate to see why do you have this behaviour and how can you solve this using a custom callback.
– Alex Mamo
Nov 14 '18 at 12:11
Hey @VandyWhite do mark the answer as correct by clicking the V type tick mark button next to the answer, and vote it up by clicking the up arrow button next to the answer, this helps people with similar question on Stack Overflow and I'd also appreciate that. Cheers!
– PradyumanDixit
Dec 26 '18 at 4:18