gpt4 book ai didi

java - 从 Google App Engine 调用 Firebase 数据库

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:02:01 26 4
gpt4 key购买 nike

我关注了这个 tutorial用于设置我的 Google App Engine 实例,我也在使用 Firebase。我的目标是将所有“计算”放在 Google App Engine 上。我想在下面调用这样的函数:

我的端点:

package productions.widowmaker110.backend;

/** An endpoint class we are exposing */
@Api(
name = "myApi",
version = "v1",
namespace = @ApiNamespace(
ownerDomain = "backend.widowmaker110.productions",
ownerName = "backend.widowmaker110.productions",
packagePath=""
)
)
public class MyEndpoint {

/** A simple endpoint method that takes a name and says Hi back */
@ApiMethod(name = "sayHi")
public MyBean sayHi(@Named("name") String name) {

// Write a message to the database
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");

// Read from the database
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
String value = dataSnapshot.getValue(String.class);
Log.d(TAG, "Value is: " + value);
}

@Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});

MyBean response = new MyBean();
response.setData("Hi, " + name);

return response;
}

}

主要 Activity :
package productions.widowmaker110.gpsweather;

// imports...

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

new EndpointsAsyncTask().execute(new Pair<Context, String>(this, "Manfred"));
}

class EndpointsAsyncTask extends AsyncTask<Pair<Context, String>, Void, String> {
private MyApi myApiService = null;
private Context context;

@Override
protected String doInBackground(Pair<Context, String>... params) {
if(myApiService == null) { // Only do this once
MyApi.Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// options for running against local devappserver
// - 10.0.2.2 is localhost's IP address in Android emulator
// - turn off compression when running against local devappserver
.setRootUrl("http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
@Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
// end options for devappserver

myApiService = builder.build();
}

context = params[0].first;
String name = params[0].second;

try {
return myApiService.sayHi(name).execute().getData();
} catch (IOException e) {
return e.getMessage();
}
}

@Override
protected void onPostExecute(String result) {
Toast.makeText(context, result, Toast.LENGTH_LONG).show();
}
}
}

我了解 Firebase 的上述代码是特定于 Android 的,因此无法在 Google App Engine 实例上运行。我想知道是否有人知道如何执行 CRUD
从 Google App Engine 后端对 firebase 数据库进行操作。任何帮助表示赞赏。

最佳答案

您需要使用 Firebase Server SDK 进行服务器端调用。您可以在此处找到有关设置和使用它的信息:

Add Firebase to your Server

Firebase Server SDK Installation & Setup

将 Firebase 与 Google Cloud Endpoints 结合使用时请注意,您需要将 Firebase 方法与 Tasks API 结合使用.由于 Firebase 方法不会阻塞,如果您不使用 Tasks,您的 Endpoint 将在您对 Firebase 进行的调用有机会返回其结果之前返回。有关使用任务的简要介绍,请查看下面的链接。这是在 2016 年 Google I/O 上的演讲。演讲者谈论的是 Android 上的 Tasks 和 Firebase,但在服务器上使用 Tasks 和 Firebase 时的概念是相同的。请注意,它们已将 Tasks API 与 Firebase Server SDK 一起包含在内。我已经跳到了直接处理任务的那部分。

Firebase SDK for Android: A tech deep dive

以下示例适用于您是否需要在 Endpoint 返回值之前处理 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 相同的参数类型目的。
    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);
    }
    }
    });
  • 调用 Task.await()阻塞当前线程直到 Task你感兴趣的已经完成。我们正在等待 TaskTaskCompletionSource 生成对象被标记为完成。此 Task当我们拨打 setResult() 时将被视为完整在 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() 的方法调用或 setValue()其中使用 DatabaseReference.CompletionListener以及一个 TaskCompletionListener。

    等待读操作完成与此类似。

    使用 addListenerForSingleValueEvent() 的示例读取操作
    DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
    YourModelClass mModelClassObject;
  • 创建一个 TaskCompletionSource用您期望的结果参数化的对象 Task这将从它产生。
    final TaskCompletionSource<YourModelClass> tcs = new TaskCompletionSource<>();
  • 生成 Task来自 TaskCompletionSource目的
    Task<YourModelClass> tcsTask = tcs.getTask();
  • 调用 addListenerForSingleValueEvent()在我们的 DatabaseReference并调用 setResult()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
    }
    });
  • 调用 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, Background Threads, and App Engine

    关于java - 从 Google App Engine 调用 Firebase 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37892336/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com