Kaitlyn Hanrahan
Kaitlyn Hanrahan

Reputation: 789

How do you use Google Cloud Platform?

I have an Android app. It uses Firebase. I want to send users notifications based on data in the Firebase Database.

I figured this was a pretty common use case, and yet nearly all tutorials were just about sending a Notification by hand using the Firebase Console. I obviously need a server to regularly look at Firebase and fire off these notifications.

I finally found a tutorial on how to do this: https://cloud.google.com/solutions/mobile/firebase-app-engine-android-studio (the example sends an email, but that's close enough for me to get Firebase and GCP talking to eachother)

But there is an error in the code provided there. Specifically this bit here causes a null pointer exception:

    FirebaseOptions options = new FirebaseOptions.Builder()
            .setServiceAccount("/WEB-INF/[my private key file].json")
            .setDatabaseUrl("https://[my firebase account].firebaseio.com/")
            .build();

I get a 500 server error on here: https://[my project ID].appspot.com/send-email.

Over at https://console.cloud.google.com I get this: NullPointerException at setServiceAccount (FirebaseOptions.java:73). The logs make it clear that the problem is what I say above.

Stack trace:

java.lang.NullPointerException
at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkNotNull (Preconditions.java:213)
at com.google.api.client.util.Preconditions.checkNotNull (Preconditions.java:127)
at com.google.api.client.util.ByteStreams.copy (ByteStreams.java:46)
at com.google.firebase.FirebaseOptions$Builder.setServiceAccount (FirebaseOptions.java:73)
at digital.simply.goalsandtasks.backend.MyServlet.doGet (MyServlet.java:88)
at javax.servlet.http.HttpServlet.service (HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service (HttpServlet.java:717)
...

So I've tried a few things.

First I changed the problematic Java code to this:

    InputStream in = Thread.currentThread().getContextClassLoader()
            .getResourceAsStream("/WEB-INF/[my private key file].json");

    FirebaseOptions options = new FirebaseOptions.Builder()
            .setServiceAccount(in)
            .setDatabaseUrl("https://[my firebase account].firebaseio.com/")
            .build();

But I'm still getting an error at that .setServiceAccount(... line.

Second, the tutorial also says to make the project manually scaled by updating the appengine-web.xml file to this:

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
   <application>myApplicationId</application>
   <version>1</version>
   <threadsafe>true</threadsafe>
   <manual-scaling>
       <instances>1</instances>
   </manual-scaling>
   <system-properties>
       <property name="java.util.logging.config.file" value="WEB-INF/logging.properties" />
   </system-properties>
</appengine-web-app>

It wasn't clear that I should, but I changed `myApplicationId' to my actual GCP Project ID.

Neither seemed to do it. Any ideas on how to fix that null pointer exception?

Upvotes: 1

Views: 498

Answers (2)

Kaitlyn Hanrahan
Kaitlyn Hanrahan

Reputation: 789

Beyond the tutorial I had to do a few things...

1) Change the name of my Project to not have spaces.
The tutorial provided code does not work with a json private key filename with spaces. And the name is from the Project Name. All my attempts to process the file name string failed. Perhaps a better Java developer could find a way. So I dumped my existing Project in the GCP Console and made a new one. Hooked the app up to that.

Then change that bit of Java back to the original version from the tutorial. Like this:

FirebaseOptions options = new FirebaseOptions.Builder()
        .setServiceAccount("/WEB-INF/[my private key file].json")
        .setDatabaseUrl("https://[my firebase account].firebaseio.com/")
        .build();

2) Add myself as an authorized sender
In the Console [https://console.cloud.google.com/] go to Settings then add my own real Google Account as an Email API authorized sender. Then replace reminder@[FIREBASE_PROJECT_ID].appspotmail.com with said email address.

Still trying to figure out how to make that an alias like "[email protected]".

3) And finally updating the code.
It seems you can just hit Build > Deploy Module to App Engine... with the same Version to upload updates.

In logging.properties I changed this line:

 # Set the default logging level for all loggers to WARNING
 .level = INFO

Then I could read my own logs here:
https://console.cloud.google.com/logs/
Which was helpful.

Anyway. I hope someday I can save some other beginner from going loopy trying to get this working.

Again the tutorial is called:
Using Firebase and App Engine Standard Environment in an Android App
https://cloud.google.com/solutions/mobile/firebase-app-engine-android-studio

Upvotes: 2

Pushkaraj Joshi
Pushkaraj Joshi

Reputation: 159

So I remember facing a similar problem while creating an app which required me to use the Firebase Cloud Messaging feature. So in order for you to bypass the console, you need to implement a back-end server which will do that for you. You can either implement the back-end server or use the cloud functions provided by firebase for this purpose. Please refer to the following links that I have attached below. Comment so I can clarify on how to precisely go about implement the messaging feature.

For using the cloud functions: https://firebase.google.com/docs/functions/

https://firebase.google.com/docs/cloud-messaging/android/client

https://firebase.google.com/docs/cloud-messaging/http-server-ref

https://firebase.google.com/docs/cloud-messaging/server

Upvotes: 0

Related Questions