我正在尝试创建REST api,以使用Firebase Server SDK和Jersey执行写入操作。
以下是我要做的:
我只想在Firebase写入操作成功或失败时返回Response。这发生在Firebase Listeners内部。然而,我尝试从侦听器返回值,但由于Firebase侦听器具有void返回类型,所以收到错误消息。
我如何从监听器返回响应?
这是我的代码。
MyEndpoint.java
@Path("/restapi")
//BaseEndpoint does Authentication operations
public class MyEndpoint extends BaseEndpoint {
public void Authenticate(String token, AuthenticationListener authenticationResultListener) {
super.Authenticate(token, authenticationResultListener);
}
@POST
@Produces("application/json")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response createCommunity(@FormParam("idToken") String idToken) {
Authenticate(idToken, new AuthenticationListener() {
@Override
public void onAuthenticationSuccess() {
// The app only has access as defined in the Security Rules
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/mysamplenode");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
String res = dataSnapshot.getKey();
//I will do some write operations on Firebase here
//If they complete successfuly only then I want to return api response
return Response.status(200).entity().build();
}
@Override
public void onCancelled(DatabaseError arg0) {
System.out.println("DatabaseError-------------" + arg0);
return Response.status(500).entity("DatabaseError").build();
}
});
}
@Override
public void onAuthenticationFailure() {
return Response.status(403).entity("Forbidden").build();
}
});
}
}
BaseEndpoint.java
public class BaseEndpoint {
public static String uid;
public void Authenticate(String token, AuthenticationListener authenticationResultListener) {
// idToken comes from the client app
FirebaseAuth.getInstance().verifyIdToken(token).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception arg0) {
System.out.println("Uid exp= " + arg0);
authenticationResultListener.onAuthenticationFailure();
}
}).addOnSuccessListener(new OnSuccessListener<FirebaseToken>() {
@Override
public void onSuccess(FirebaseToken decodedToken) {
uid = decodedToken.getUid();
System.out.println("Uid= " + uid);
authenticationResultListener.onAuthenticationSuccess();
}
});
}
}
我回答这个问题可能有点晚,但在试用Firebase服务器SDK后,我发现您可以在SDK中创建一个可用的任务以同步等待响应。下面的片段可能会对您有所帮助:
public class BaseEndpoint {
public static String uid;
public void Authenticate(String token, AuthenticationListener authenticationResultListener) {
// idToken comes from the client app
FirebaseToken firebaseToken = null;
try {
Task<FirebaseToken> authTask = FirebaseAuth.getInstance().verifyIdToken(token);
Tasks.await(authTask);
firebaseToken = authTask.getResult();
} catch (Exception e) {
authenticationResultListener.onAuthenticationFailure();
}
uid = firebaseToken.getUid();
System.out.println("Uid= " + uid);
authenticationResultListener.onAuthenticationSuccess();
}
}
所以我猜测Firebase SDK本质上是异步的。在这种情况下,如果您使用的是Jersey 2.x,则可以使用异步服务器支持。您只需调用AsyncResponse。恢复(响应)
。例如
@POST
@Produces("application/json")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void createCommunity(@FormParam("idToken") String idToken,
@Suspended final AsyncResponse response) {
Authenticate(idToken, new AuthenticationListener() {
@Override
public void onAuthenticationSuccess() {
DatabaseReference ref = FirebaseDatabase.getInstance()
.getReference("/mysamplenode");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
String res = dataSnapshot.getKey();
response.resume(Response.status(200).entity().build());
}
@Override
public void onCancelled(DatabaseError arg0) {
response.resume(Response.status(500).entity("DatabaseError").build());
}
});
}
@Override
public void onAuthenticationFailure() {
response.resume(Response.status(403).entity("Forbidden").build());
}
});
}
如果你使用的是Jersey 1.x,实际上没有异步选项。您只需要用< code>CountDownLatch阻塞流,在回调中分配一个本地< code>Response,然后递减计数。
@POST
@Produces("application/json")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void createCommunity(@FormParam("idToken") String idToken) {
Response response;
CountDownLatch latch = new CountDownLatch(1);
Authenticate(idToken, new AuthenticationListener() {
@Override
public void onAuthenticationSuccess() {
DatabaseReference ref = FirebaseDatabase.getInstance()
.getReference("/mysamplenode");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
String res = dataSnapshot.getKey();
response = Response.status(200).entity().build();
latch.countDown();
}
@Override
public void onCancelled(DatabaseError arg0) {
response = Response.status(500).entity("DatabaseError").build();
latch.countDown();
}
});
}
@Override
public void onAuthenticationFailure() {
response = Response.status(403).entity("Forbidden").build();
latch.countDown();
}
});
latch.await();
return response;
}
我有一个CustomRequest类: } 然后我有我的类JSONRequest: } 我想做的是在我的postRequest方法中,有一个CustomRequest类的对象叫做JSONObject Request,我想将JSONObject响应变量从onResponse方法返回给父postRequest方法,我在以下位置得到一个错误: 因为它告诉我方法的返回类型是void,请告诉我我做错了什么,
问题内容: 我有一个私有方法,该方法接受一个整数值列表,并返回一个整数值列表。我如何使用电源模拟进行测试。我是powermock的新手。我可以通过简单的模拟进行测试吗?怎么样.. 问题答案: 从该文件中,部分被称为“公共- 旁路封装”: 使用Whitebox.invokeMethod(..)调用实例或类的私有方法。 您也可以在同一部分中找到示例。
问题内容: 我想做这样的事情: 不幸的是,列表追加未返回修改后的列表。 那么,我如何允许返回新列表? 问题答案: 不要使用追加而是串联: 这将返回一个 新 列表。不会受到影响。如果你需要有受影响的 还有 既可以使用,无论如何,然后分配分开(复印件)。
我试图编写一个方法,它接受@PathVariable参数,并将用户重定向到一个jsp文件。 @pathvariable(value=“customerId”)字符串customerId @pathvariable(name=“customerId”)字符串customerId @pathvariable(“customerId”)字符串customerId 谢谢你的帮助。
我想返回与我在中获得的参数具有相同对象的相同列表。如果我得到
关于方法何时应该返回CompletableFuture的一般准则是什么?假设有两个类A和B,其中类B有一个执行大量IO的方法performTask(),类A调用performTask()方法在Java可以使用以下方法编写多线程代码: < li >让方法的调用方决定是否使用ThreadPool异步执行方法。在这种情况下,A将异步调用performTask()方法,这样类B就不需要使其方法异步。 <