Reputation: 1897
I was looking for some similar questions but as far as I know none of them are Java related. I want to call a AWS lambda function within which I am connecting to a Firebase database. The problem is that the handler executes before I get the needed data from Firebase.
@Override
public String handleRequest(Request input, Context context) {
try {
FileInputStream serviceAccountInputStream = new FileInputStream(FIREBASE_SERVICE_ACCOUNT_CREDENTIALS_PATH);
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.fromCertificate(serviceAccountInputStream))
.setDatabaseUrl(FIREBASE_DATABASE_URL)
.build();
FirebaseApp.initializeApp(options);
DatabaseReference ref = FirebaseDatabase
.getInstance()
.getReference("users/" + input.getUid());
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.print(dataSnapshot);
// TODO: Do computations on data and return results
}
@Override
public void onCancelled(DatabaseError databaseError) {
System.out.print("Canceled");
// TODO: Return error
}
});
} catch (Exception e) {
e.printStackTrace();
}
// TODO: Return computed results
return "This could be the start of something new.";
}
I need to read data from the Firebase database, do some computations with it and return the computed results to the user. How can I achieve this? :)
Upvotes: 1
Views: 608
Reputation: 356
You can wait for the async code to finish by using a CountDownLatch.
Before calling the async code you create the CountDownLatch:
final CountDownLatch countDownLatch = new CountDownLatch(1);
Then at the end of the callback methods you count down the latch:
countDownLatch.countDown();
Then after the async method you wait for the CountDownLatch to be counted down:
waitForCountdownLatch(countDownLatch);
private static void waitForCountdownLatch(CountDownLatch countDownLatch) {
try {
countDownLatch.await();
} catch (InterruptedException e) {
log.error(e);
e.printStackTrace();
}
}
So with your code it would be:
@Override
public String handleRequest(Request input, Context context) {
final CountDownLatch countDownLatch = new CountDownLatch(1);
final Object[] singleValue = new Object[1];
final DatabaseError[] firebaseError = new DatabaseError[1];
try {
FileInputStream serviceAccountInputStream = new FileInputStream(FIREBASE_SERVICE_ACCOUNT_CREDENTIALS_PATH);
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.fromCertificate(serviceAccountInputStream))
.setDatabaseUrl(FIREBASE_DATABASE_URL)
.build();
FirebaseApp.initializeApp(options);
DatabaseReference ref = FirebaseDatabase
.getInstance()
.getReference("users/" + input.getUid());
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.print(dataSnapshot);
Object snapshotValue = dataSnapshot.getValue();
if(snapshotValue != null) {
singleValue[0] = snapshotValue;
}
countDownLatch.countDown();
}
@Override
public void onCancelled(DatabaseError databaseError) {
System.out.print("Canceled");
firebaseError0] = databaseError;
countDownLatch.countDown();
}
});
} catch (Exception e) {
e.printStackTrace();
countDownLatch.countDown();
}
waitForCountdownLatch(countDownLatch);
if(firebaseError[0] != null) {
System.out.print(firebaseError[0].toException().getMessage());
}
if(singleValue[0] != null) {
// do something with result
}
return "This could be the start of something new.";
}
private void waitForCountdownLatch(CountDownLatch countDownLatch) {
try {
countDownLatch.await();
} catch (InterruptedException e) {
log.error(e);
e.printStackTrace();
}
}
Upvotes: 1