I'm using Firebase JAVA sdk in my Spring Boot application.
Trying to verify a firebase token:
Map resp = new HashMap();
Task task = FirebaseAuth.getInstance().verifyIdToken(info.getToken())
.addOnSuccessListener(new OnSuccessListener() {
@Override
public void onSuccess(FirebaseToken decodedToken) {
logger.info(decodedToken.getClaims());
String uid = decodedToken.getUid();
User user = userDao.loadUserByUID(uid);
if (user == null) {
...........
}
SimpleSignInAdapter.signin(user.getUsername());
resp.put("status", "success");
resp.put("token", jwtTokenProvider.createToken(SecurityContextHolder.getContext().getAuthentication()));
logger.info(resp);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
resp.put("status", "fail");
resp.put("message", e.getMessage());
}
});
try {
Tasks.await(task);
logger.info(resp);
return resp;
} catch (ExecutionException | InterruptedException e) {
resp.put("status", "fail");
resp.put("message", e.getMessage());
return resp;
}
Tasks.await(task) suppose to block a code execution until task is finished. However it doesn't block the code and logger.info(resp); return resp; getting executed before it's finished:
2017-09-20 16:10:30,613 INFO [http-nio-8080-exec-1] impl.FirebaseServiceImpl (FirebaseServiceImpl.java:98) - {}
2017-09-20 16:10:30,613 INFO [pool-2-thread-2] impl.FirebaseServiceImpl$2 (FirebaseServiceImpl.java:56) - {"aud":******" ******}}
2017-09-20 16:10:43,966 INFO [pool-2-thread-2] impl.FirebaseServiceImpl$2 (FirebaseServiceImpl.java:84) -{status=success, token=......}
What can be a possible reason ?
解决方案
I think you're misinterpreting the logs. Tasks.await() is doing its job. Bear in mind that the success listener is not obligated to execute precisely before or after Tasks.await(). It will execute some time after the task is complete, just like Tasks.await() returns some time after the task is complete. Also note that the log lines are coming from two different threads: http-nio-8080-exec-1 and pool-2-thread-2, and there's no guarantee about the order in which those two threads will continue when the task is complete.
Now, if you want to ensure that the thread running Tasks.await() executes only after the success listener, you'll have to use something like a CountDownLatch to block the first thread until the work in the success listener is complete.