Google Cloud Endpoint在端点

时间:2016-11-22 02:42:31

标签: java android google-app-engine firebase-authentication google-compute-engine

我正在尝试验证由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端点执行异步代码。但无处可去。我得到的是关于代码执行的东西,在完成之前阻塞然后返回用户。但是如何进行编码以使上述异步代码成为阻塞?

1 个答案:

答案 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) {
    
    }
    

那就是它。希望这可能有所帮助。