To make server-side calls, you need to use the Firebase Server SDK. You can find installation and usage information here:
Add Firebase to your server
Install and configure the Firebase Server SDK
When using Firebase with Google Cloud Endpoints, be aware that you will need to use Firebase methods in conjunction with the task APIs . Since Firebase methods are not blocked, unless you use Tasks, your endpoint will return before the call you made in Firebase has the ability to return its result. For a brief introduction to using tasks, check out the link below. This is a conversation defined in Google I / O 2016. The speaker talks about tasks and Firebase on Android, but the concepts are the same when using Tasks and Firebase on the server. Note that they have enabled the task API with the Firebase Server SDK. I missed the part of the conversation that directly relates to tasks.
Firebase SDK for Android: a deep dive in technology
The following are examples if you need to process the result from your Firebase read / write operation before your endpoint returns a value or if other code depends on the result of the Firebase read / write operation. These are server side examples. I'm going to assume that you care about whether the write operation was successful. There may be more efficient ways to do these server side operations, but this is what I have done so far.
An example of a write operation using setValue ():
DatabaseReference ref = FirebaseDatabase.getInstance().getReference(); YourModelClass obj = new YourModelClass();
When calling the setValue() method, it returns a Task object, keep a reference to it.
Task<Void> setValueTask = ref.setValue(obj);
Create a TaskCompletionSource object. This object must be parameterized according to the type of result of your choice. I will use Boolean as the result type for this example.
final TaskCompletionSource<Boolean> tcs = new TaskCompletionSource<>();
Create a Task from the TaskCompletionSource created in step 2. Again, the generated Task should use the same parameter type as the TaskCompletionSource object.
Task<Boolean> tcsTask = tcs.getTask();
Add a completion listener to the Task that was called by the setValue() call. In the completion listener, set the corresponding result to the Task created in step 3. Calling setResult() on your TaskCompletionSouce object will mark the Task created from it as completed. This is important for step 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() to block the current thread until the Task you are interested in finishes. We expect the Task generated by the TaskCompletionSource to be marked as completed. This Task will be considered complete when we call setResult() on the TaskCompletionSource used to generate the Task , as it was in step 4. After completion, it will return the result.
try { Boolean result = Tasks.await(tcsTask); }catch(ExecutionException e){ //handle exception }catch (InterruptedException e){ //handle exception }
That is, the current thread will block until Tasks.await() returns a value. You can also (and should) set the timeout value in the Tasks.await() method if you want the current thread to block indefinitely.
If you were only interested in whether or not the Task generated by setValue() was completed and did not care whether it was successful or not, you can skip creating TaskCompletionSource and just use Tasks.await() directly on that Task . The same thing works for updateChildren() . And if you like, you can simply use the method calls for updateChilden() or setValue() , which use the DatabaseReference.CompletionListener along with the TaskCompletionListener.
Waiting for the read to complete is similar.
Example read operation using addListenerForSingleValueEvent ()
DatabaseReference ref = FirebaseDatabase.getInstance().getReference(); YourModelClass mModelClassObject;
Create a TaskCompletionSource object parameterized with the result that you expect from the Task to be generated from it.
final TaskCompletionSource<YourModelClass> tcs = new TaskCompletionSource<>();
Generate a Task from the TaskCompletionSource object
Task<YourModelClass> tcsTask = tcs.getTask();
Call addListenerForSingleValueEvent() on our DatabaseReference and call setResult() on the Task generated in step 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){
Call Tasks.await() to block the current thread until the Task you are interested in finishes. Task will be considered complete when we call setResult() , as it was in step 3, and return the result.
try { mModelClassObject = Tasks.await(tcsTask); }catch(ExecutionException e){ //handle exception }catch (InterruptedException e){ //handle exception }
As mentioned above, you can use the Tasks.await() method along with a timeout value to prevent the current thread from being blocked.
As in the heads, I found that Firebase does not kill the background thread, which is used for its operations. This means that the GAE instance never works. Check out this topic for more information:
Firebase, Background Threads and App Engine