我有一个Android应用。它使用Firebase。我想根据Firebase数据库中的数据向用户发送通知。
我认为这是一个非常常见的用例,但几乎所有教程都只是使用Firebase控制台手动发送通知。我显然需要一台服务器来定期查看Firebase并触发这些通知。
我终于找到了一个如何执行此操作的教程:https://cloud.google.com/solutions/mobile/firebase-app-engine-android-studio (该示例发送了一封电子邮件,但这足以让我让Firebase和GCP互相交谈)
但是那里提供的代码存在错误。具体来说,此位会导致空指针异常:
FirebaseOptions options = new FirebaseOptions.Builder()
.setServiceAccount("/WEB-INF/[my private key file].json")
.setDatabaseUrl("https://[my firebase account].firebaseio.com/")
.build();
我在这里收到500服务器错误:https://[my project ID].appspot.com/send-email
。
在https://console.cloud.google.com
结束时,我得到了这个:NullPointerException at setServiceAccount (FirebaseOptions.java:73)
。日志清楚地表明问题就在我上面说的。
堆栈追踪:
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)
...
所以我尝试了一些事情。
首先,我将有问题的Java代码更改为:
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();
但我仍然在.setServiceAccount(...
行收到错误。
其次,本教程还说通过将appengine-web.xml
文件更新为手动缩放项目:
<?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>
我不清楚我应该这样,但我将`myApplicationId'更改为我的实际GCP项目ID。
似乎都没有这样做。关于如何修复空指针异常的任何想法?
答案 0 :(得分:2)
除了教程之外,我还要做一些事情......
1)将Project的名称更改为不包含空格。
提供的教程代码不适用于带空格的json私钥文件名。名称来自项目名称。我处理文件名字符串的所有尝试都失败了。也许更好的Java开发人员可以找到方法。所以我将现有的项目转储到GCP控制台并创建了一个新项目。把应用程序搞定了。
然后从教程中将Java的那一部分更改回原始版本。像这样:
FirebaseOptions options = new FirebaseOptions.Builder()
.setServiceAccount("/WEB-INF/[my private key file].json")
.setDatabaseUrl("https://[my firebase account].firebaseio.com/")
.build();
2)将自己添加为授权发件人
在控制台[https://console.cloud.google.com/]中转到“设置”,然后将我自己的真实Google帐户添加为电子邮件API授权发件人。然后用所述电子邮件地址替换reminder@[FIREBASE_PROJECT_ID].appspotmail.com
。
仍在努力弄清楚如何制作一个像“reminder@mydomain.com”这样的别名。
3)最后更新代码。
您似乎可以使用相同的版本点击Build > Deploy Module to App Engine...
来上传更新。
在logging.properties
我改变了这一行:
# Set the default logging level for all loggers to WARNING
.level = INFO
然后我可以在这里阅读我自己的日志:
https://console.cloud.google.com/logs/
这很有帮助。
无论如何。我希望有一天我可以节省其他一些初学者来试图让这个工作变得循环。
再次调用该教程:
在Android应用中使用Firebase和App Engine标准环境
https://cloud.google.com/solutions/mobile/firebase-app-engine-android-studio
答案 1 :(得分:0)
所以我记得在创建需要我使用Firebase云消息传递功能的应用时面临类似的问题。因此,为了让您绕过控制台,您需要实现一个后端服务器,它将为您完成。您可以实现后端服务器,也可以使用firebase提供的云功能来实现此目的。请参阅我在下面附带的以下链接。评论所以我可以澄清如何准确地实现消息传递功能。
使用云功能: 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