boo*_*y99 8 java google-app-engine android firebase
我按照本教程设置了我的Google App Engine实例,我也在使用Firebase.我的目标是将所有"计算"放在Google App Engine上.我想调用下面这样的函数:
MyEndpoint:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
主要活动:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我了解Firebase的上述代码是特定于Android的,因此在Google App Engine实例上运行不起作用.我想知道是否有人知道如何从Google App Engine后端对firebase数据库执行CRUD操作.任何帮助表示赞赏.
Kev*_*eil 11
您需要使用Firebase Server SDK进行服务器端调用.您可以在此处找到有关设置和使用它的信息:
将Firebase与Google Cloud Endpoints一起使用时,请注意您需要将Firebase方法与Tasks API结合使用.由于Firebase方法没有阻止,如果您不使用任务,则在您对Firebase进行的呼叫有机会返回其结果之前,您的端点将返回.有关使用任务的简要介绍,请查看以下链接.这是在Google I/O 2016上发表的演讲.演讲者正在讨论Android上的任务和Firebase,但在服务器上使用Tasks和Firebase时的概念是相同的.请注意,他们已将Tasks API与Firebase Server SDK一起包含在内.我已经跳过直接涉及任务的谈话部分.
适用于Android的Firebase SDK:深入了解技术
以下示例是您需要在Endpoint返回值之前处理Firebase读/写操作的结果,或者其他代码是否依赖于Firebase读/写操作的结果.这些是服务器端示例.我将假设你关心写操作是否成功.可能有更好的方法来执行这些服务器端操作,但这是我到目前为止所做的.
使用setValue()进行示例写入操作:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
YourModelClass obj = new YourModelClass();
Run Code Online (Sandbox Code Playgroud)
当对setValue()方法进行调用时,它返回一个Task对象,保持对它的引用.
Task<Void> setValueTask = ref.setValue(obj);
Run Code Online (Sandbox Code Playgroud)创建一个TaskCompletionSource对象.应使用您选择的结果类型对此对象进行参数化.我将使用Boolean此示例的结果类型.
final TaskCompletionSource<Boolean> tcs = new TaskCompletionSource<>();
Run Code Online (Sandbox Code Playgroud)Task从TaskCompletionSource步骤2中创建的内容生成a .同样,生成的Task应使用与TaskCompletionSource对象相同的参数类型.
Task<Boolean> tcsTask = tcs.getTask();
Run Code Online (Sandbox Code Playgroud)添加完成侦听器到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);
}
}
});
Run Code Online (Sandbox Code Playgroud)调用Task.await()阻止当前线程直到Task您感兴趣已完成.我们正在等待对象Task生成的TaskCompletionSource标记完成.这Task时候,我们的通话将被认为是完整setResult()的TaskCompletionSource用来生成Task正如我们在第4步做.一旦完成,它将返回结果.
try {
Boolean result = Tasks.await(tcsTask);
}catch(ExecutionException e){
//handle exception
}catch (InterruptedException e){
//handle exception
}
Run Code Online (Sandbox Code Playgroud)就是这样,当前线程将阻塞,直到Tasks.await()返回一个值.Tasks.await()如果要保持当前线程无限期地被阻止,您还可以(并且应该)在方法上设置超时值.
如果您只对完成Task生成setValue()并且不关心它是否成功感兴趣,那么您可以跳过创建TaskCompletionSource并Tasks.await()直接使用它Task.同样适用于updateChildren().如果你喜欢,你可以使用方法调用updateChilden()或setValue()使用DatabaseReference.CompletionListener与TaskCompletionListener一起使用.
等待读取操作完成是类似的.
使用addListenerForSingleValueEvent()进行示例读取操作
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
YourModelClass mModelClassObject;
Run Code Online (Sandbox Code Playgroud)
创建一个TaskCompletionSource参数化的对象,该对象具有您希望从中Task生成的结果.
final TaskCompletionSource<YourModelClass> tcs = new TaskCompletionSource<>();
Run Code Online (Sandbox Code Playgroud)Task从TaskCompletionSource对象生成a
Task<YourModelClass> tcsTask = tcs.getTask();
Run Code Online (Sandbox Code Playgroud)拨打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
}
});
Run Code Online (Sandbox Code Playgroud)调用Tasks.await()阻止当前线程直到Task您感兴趣已完成.在Task当我们调用将被认为是完整的setResult(),因为我们没有在第3步,并返回结果.
try {
mModelClassObject = Tasks.await(tcsTask);
}catch(ExecutionException e){
//handle exception
}catch (InterruptedException e){
//handle exception
}
Run Code Online (Sandbox Code Playgroud)如上所述,您可以使用该Tasks.await()方法以及超时值来防止当前线程无限期地被阻止.
就像抬头一样,我发现Firebase不会杀死用于其操作的后台线程.这意味着GAE实例永远不会空闲.查看此主题以获取更多信息:
| 归档时间: |
|
| 查看次数: |
2404 次 |
| 最近记录: |