我正在尝试验证由GCE端点中的Android中的Firebase身份验证库创建的客户端令牌。
可以找到如何执行此操作的指南here
基本上我需要从终点调用此代码片段(即服务器后端代码而不是android代码)。
FirebaseAuth.getInstance().verifyIdToken(idToken)
.addOnSuccessListener(new OnSuccessListener<FirebaseToken>() {
@Override
public void onSuccess(FirebaseToken decodedToken) {
String uid = decodedToken.getUid();
// ...
}
});
假设我想执行该代码并将用户返回到Android客户端代码。我该怎么做?
这是我的示例代码,没有意义。但它证明了我想做的事情!
@ApiMethod(name = "serverAuth")
public MyUser serverAuth(@Named("token") String token) {
FirebaseAuth.getInstance().verifyIdToken(token)
.addOnSuccessListener(new OnSuccessListener<FirebaseToken>() {
@Override
public void onSuccess(FirebaseToken decodedToken) {
String uid = decodedToken.getUid();
String email = decodedToken.getEmail();
String name = decodedToken.getName();
Map<String, Object> claims = decodedToken.getClaims();
String claimString = "";
for (Object claim : claims.values()) {
claimString += claims.toString();
}
MyUser user = new MyUser(uid, email, name, claimString);
//How to return this user?
}
});
//This is compile error since user varriable does not exist here
return user;
}
我有谷歌搜索如何在GCE端点执行异步代码。但无处可去。我得到的是关于代码执行的东西,在完成之前阻塞然后返回用户。但是如何进行编码以使上述异步代码成为阻塞?
答案 0 :(得分:4)
CountDownLatch 是您需要的神奇类。它会让你等到OnSuccessListener实际完成。
以这种方式调整您的方法:(我删除了导致MyUser创建的步骤,以便专注于重点。)
@ApiMethod(name = "serverAuth")
public MyUser serverAuth(@Named("token") String token) {
final List<MyUser> users = new ArrayList<>();
final CountDownLatch cdl = new CountDownLatch(1);
FirebaseAuth.getInstance().verifyIdToken(token)
.addOnSuccessListener(new OnSuccessListener<FirebaseToken>() {
@Override
public void onSuccess(FirebaseToken decodedToken) {
// ... init uid, email, name and claimString
users.add(new MyUser(uid, email, name, claimString));
cdl.countDown();
}
});
try {
cdl.await(); // This line blocks execution till count down latch is 0
} catch (InterruptedException ie) {
}
if (users.size() > 0) {
return users.get(0);
} else {
return null ;
}
}
这是您需要的基本版本。恕我直言,它还需要2个改进:
您还应该考虑失败的可能性:
FirebaseAuth.getInstance().verifyIdToken(token)
.addOnSuccessListener(new OnSuccessListener<FirebaseToken>() {
@Override
public void onSuccess(FirebaseToken decodedToken) {
cdl.countDown();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// log error, ...
cdl.countDown();
}
});
您还应该考虑没有调用任何侦听器。在这种情况下,您的方法永远不会返回。为避免这种情况,您可以在await()方法上设置超时:
try {
// This line blocks execution till count down latch is 0
// or after 30 seconds.
cdl.await(30l, TimeUnit.SECONDS);
} catch (InterruptedException ie) {
}
那就是它。希望这可能有所帮助。