您需要使用 Firebase Server SDK 进行服务器端调用。您可以在此处找到有关设置和使用它的信息:
将 Firebase 添加到您的服务器 https://firebase.google.com/docs/server/setup
Firebase 服务器 SDK 安装和设置 https://firebase.google.com/docs/database/server/start
将 Firebase 与 Google Cloud Endpoints 结合使用时,请注意,您需要将 Firebase 方法与任务API https://firebase.google.com/docs/reference/serverreference/com/google/firebase/tasks/package-summary。由于 Firebase 方法不会阻塞,因此如果您不使用任务,您的端点将在您对 Firebase 进行的调用有机会返回其结果之前返回。有关使用任务的简要介绍,请查看下面的链接。这是 Google I/O 2016 上的一次演讲。演讲者谈论的是 Android 上的任务和 Firebase,但在服务器上使用任务和 Firebase 时的概念是相同的。请注意,他们已将任务 API 包含在 Firebase Server SDK 中。我已经跳到了演讲中直接涉及任务的部分。
适用于 Android 的 Firebase SDK:技术深入探讨 https://youtu.be/AJqakuas_6g?t=386
以下示例适用于您是否需要在端点返回值之前处理 Firebase 读/写操作的结果,或者其他代码取决于 Firebase 读/写操作的结果。这些是服务器端示例。我假设您关心写入操作是否成功。可能有更好的方法来执行这些服务器端操作,但这就是我到目前为止所做的。
使用 setValue() 的示例写入操作:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
YourModelClass obj = new YourModelClass();
-
当拨打电话时setValue()
方法它返回一个Task
对象,保留对其的引用。
Task<Void> setValueTask = ref.setValue(obj);
-
创建一个TaskCompletionSource
目的。应使用您选择的结果类型对该对象进行参数化。我要使用Boolean
作为本示例的结果类型。
final TaskCompletionSource<Boolean> tcs = new TaskCompletionSource<>();
-
生成一个Task
来自TaskCompletionSource
这是在步骤 2 中创建的。同样,生成的Task
应使用与TaskCompletionSource
object.
Task<Boolean> tcsTask = tcs.getTask();
-
添加一个完成监听器Task
这是通过调用生成的setValue()
。在完成监听器中设置适当的结果Task
在步骤 3 中创建。 调用setResult()
在你的TaskCompletionSouce
对象将标记Task
从它创建为完整的。这对于第 5 步很重要。
setValueTask.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
tcs.setResult(true);
}else{
tcs.setResult(false);
}
}
});
-
Call Task.await()
阻塞当前线程直到Task
您感兴趣的已完成。我们正在等待Task
由产生的TaskCompletionSource
要标记为完成的对象。这Task
当我们调用时将被认为完成setResult()
on the TaskCompletionSource
用于生成Task
正如我们在步骤 4 中所做的那样。完成后,它将返回结果。
try {
Boolean result = Tasks.await(tcsTask);
}catch(ExecutionException e){
//handle exception
}catch (InterruptedException e){
//handle exception
}
就是这样,当前线程将阻塞,直到Tasks.await()
返回一个值。您还可以(并且应该)设置一个超时值Tasks.await()
如果您想防止当前线程无限期地阻塞,请使用此方法。
如果您只关心是否Task
产生于setValue()
已完成,不关心是否成功,则可以跳过创建TaskCompletionSource
只需使用Tasks.await()
直接在那Task
。同样适用于updateChildren()
。如果你愿意,你可以使用方法调用updateChilden()
or setValue()
其中使用一个DatabaseReference.CompletionListener
以及 TaskCompletionListener。
等待读取操作完成的情况类似。
使用 addListenerForSingleValueEvent() 的示例读取操作
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
YourModelClass mModelClassObject;
-
创建一个TaskCompletionSource
对象参数化为您期望的结果Task
将从中生成。
final TaskCompletionSource<YourModelClass> tcs = new TaskCompletionSource<>();
-
生成一个Task
来自TaskCompletionSource
object
Task<YourModelClass> tcsTask = tcs.getTask();
-
Call addListenerForSingleValueEvent()
on our DatabaseReference
并打电话setResult()
on the Task
在步骤 2 中生成。
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
YourModelClass result = dataSnapshot.getValue(YourModelClass.class);
if(result != null){
tcs.setResult(result);
}
}
@Override
public void onCancelled(DatabaseError databaseError){
//handle error
}
});
-
Call Tasks.await()
阻塞当前线程直到Task
您感兴趣的已完成。这Task
当我们调用时将被认为完成setResult()
正如我们在步骤 3 中所做的那样,并将返回结果。
try {
mModelClassObject = Tasks.await(tcsTask);
}catch(ExecutionException e){
//handle exception
}catch (InterruptedException e){
//handle exception
}
如上所述,您可以使用Tasks.await()
方法以及超时值以防止当前线程无限期地阻塞。
需要注意的是,我发现 Firebase 不会终止用于其操作的后台线程。这意味着 GAE 实例永远不会空闲。查看此线程以获取更多信息:
Firebase、后台线程和 App Engine https://groups.google.com/forum/#!topic/google-appengine/U2f9dLHsck4