当前位置: 首页 > 知识库问答 >
问题:

来自Java而非Firebase控制台的Firebase云消息通知

解晟睿
2023-03-14

我是Firebase新手,当我的Java应用程序尝试使用客户端的Firebase令牌发送通知/消息时,我遇到了一些错误,例如发送者id不匹配和HTTP状态401的身份验证错误。请注意,使用Firebase控制台,我能够将消息发送到客户端。

对于客户端应用程序,我执行了以下操作:

  1. 从这里克隆Firebase消息传递快速入门应用--https://github.com/firebase/quickstart-android/tree/master/messaging--已经通过Firebase依赖项等进行了设置。在Android Studio中加载克隆的应用程序。
  2. 使用Firebase控制台,创建了一个名为我的通知客户端的新项目,并添加了一个使用com.google.firebase.quickstart.fcm作为Android应用程序包名称的应用程序。
  3. 下载了添加到新创建项目的Android应用程序的google-services.json文件,并将其复制到消息/app/文件夹中,并与来自Android Studio内的等级文件同步。
  4. 创建一个模拟器,并在Android Studio中运行应用程序。当应用程序加载到模拟器中时,单击Log Token按钮,在Android Studio中的Android Monitor选项卡中捕获客户端的Firebase令牌。
  5. 使用Firebase控制台,选择新创建的项目我的通知客户端,单击左窗格中的通知链接,并通过粘贴上一步捕获的Firebase令牌向设备发送通知。

这很有效!下一步是使用单独的简单Java应用程序(最终将成为通知服务器)将通知发送到客户端,而不是使用Firebase控制台。

为了实现这一点,我遵循了这里概述的步骤https://firebase.google.com/docs/server/setup#prerequisites.具体来说,这些是我执行的步骤:

  1. 在Firebase控制台中创建了一个名为My Notification Server的新项目。
    <dependency>
      <groupId>com.google.gcm</groupId>
      <artifactId>gcm-server</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>com.googlecode.json-simple</groupId>
      <artifactId>json-simple</artifactId>
      <version>1.1.1</version>
    </dependency>
    <dependency>
      <groupId>com.google.firebase</groupId>
      <artifactId>firebase-server-sdk</artifactId>
      <version>3.0.0</version>
    </dependency>

>

  • 然后,我扩展了com.google.android.gcm.sender.sender以创建FCMSender,并覆盖受保护的方法getConnection(字符串url)以使用新的FCMendpoint,如下所示:

    class FCMSender extends Sender {
    
        public FCMSender(String key) {
            super(key);
        }
    
        @Override
        protected HttpURLConnection getConnection(String url) throws IOException {
            String fcmUrl = "https://fcm.googleapis.com/fcm/send";
            return (HttpURLConnection) new URL(fcmUrl).openConnection();
        }
    }
    

    Java应用程序的main()方法如下所示:

    public static void main(String[] args) {
        // Obtain serverKey from Project Settings -> Cloud Messaging tab
        // for "My Notification Client" project in Firebase Console.
        String serverKey = <get_server_key_from_firebase_console>;
        Thread t = new Thread() {
            public void run(){ 
                try {
                    Sender sender = new FCMSender(serverKey);
                    Message message = new Message.Builder()
                                      .collapseKey("message")
                                      .timeToLive(3)
                                      .delayWhileIdle(true)
                                      .addData("message", "Notification from Java application");
                                      .build();  
    
                    // Use the same token(or registration id) that was earlier
                    // used to send the message to the client directly from
                    // Firebase Console's Notification tab.
                    Result result = sender.send(message,
                "APA91bFfIFjSCcSiJ111rbmkpnMkZY-Ej4RCpdBZFZN_mYgfHwFlx-M1UXS5FqDBcN8x1efrS2md8L9K_E9N21qB-PIHUqQwmF4p7Y3U-86nCGH7KNkZNjjz_P_qjcTR0TOrwXMh33vp",
                        1);
                    System.out.println("Result: " + result.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            };
            t.start;
            try {
                t.join();
            }
            catch (InterruptedException iex) {
                iex.printStackTrace();
            }
        }
    

    当我运行Java应用程序时,会出现MismatchSenderId错误。我尝试使用curl进行故障排除,如下所示,但得到了相同的错误:

    $ skey=<obtained_from_project_settings_cloud_messaging_tab_in_firebase_console>
    $ curl -X POST --header "Authorization: key=$skey" \
      --Header "Content-Type: application/json" \
      https://fcm.googleapis.com/fcm/send \
      -d "{\"to\":\"APA91bFfIFjSCcSiJ111rbmkpnMkZY-Ej4RCpdBZFZN_mYgfHwFlx-M1UXS5FqDBcN8x1efrS2md8L9K_E9N21qB-PIHUqQwmF4p7Y3U-86nCGH7KNkZNjjz_P_qjcTR0TOrwXMh33vp\",\"data\":{\"message\":\"Yellow\"}}"
    
    {"multicast_id":7391851081942579857,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}
    

    而不是使用项目设置中列出的服务器键

    Firebase留档的错误代码说明了MismatchSenderId

    不匹配的发件人200错误:不匹配的SenderId
    注册令牌绑定到某个发件人组。当客户端应用注册FCM时,它必须指定允许哪些发件人发送消息。向客户端应用发送消息时,应使用其中一个发件人ID。如果切换到其他发件人,现有注册令牌将无法工作。

    我不知道在Firebase控制台的哪里/如何配置Android应用程序(已添加到我的通知客户端项目)以接收消息。

    在此方面的任何帮助,将不胜感激!


  • 共有1个答案

    通京
    2023-03-14

    我也是最近才开始使用Firebase的,之前没有使用Google Cloud消息传递的经验。例如,目前没有用于Firebase云消息传递的服务器端SDK。

    要从应用服务器向移动客户端发送通知/消息,您需要实现自己的HTTP和/或XMPP方法。看见https://firebase.google.com/docs/cloud-messaging/

    我的测试代码,使用HTTP:

    public CompletableFuture<String> fcmTest1() {
        // https://firebase.google.com/docs/cloud-messaging/http-server-ref
        String host = "fcm.googleapis.com";
        String requestURI = "/fcm/send";
        String CLIENT_TOKEN = "ASK_YOUR_MOBILE_CLIENT_DEV"; // https://developers.google.com/instance-id/
    
        CompletableFuture<String> fut = new CompletableFuture<>();
        JsonObject body = new JsonObject();
        // JsonArray registration_ids = new JsonArray();
        // body.put("registration_ids", registration_ids);
        body.put("to", CLIENT_TOKEN);
        body.put("priority", "high");
        // body.put("dry_run", true);
    
        JsonObject notification = new JsonObject();
        notification.put("body", "body string here");
        notification.put("title", "title string here");
        // notification.put("icon", "myicon");
    
        JsonObject data = new JsonObject();
        data.put("key1", "value1");
        data.put("key2", "value2");
    
        body.put("notification", notification);
        body.put("data", data);
    
        HttpClientRequest hcr = httpsClient.post(443, host, requestURI).handler(response -> {
            response.bodyHandler(buffer -> {
                logger.debug("FcmTest1 rcvd: {}, {}", response.statusCode(), buffer.toString());
                if (response.statusCode() == 200) {
                    fut.complete(buffer.toString());
                } else {
                    fut.completeExceptionally(new RuntimeException(buffer.toString()));
                }
            });
        });
        hcr.putHeader("Authorization", "key=" + Utils.FIREBASE_SERVER_KEY)
            .putHeader("content-type", "application/json").end(body.encode());
        return fut;
    }
    

    注意:超文本传输协议客户端和json是由vertx(http://vertx.io/)提供的,但希望代码能清楚地显示正在发生的事情,这样你就可以随心所欲地使用了。

     类似资料:
    • 问题内容: 我是Firebase的新手,我的Java应用程序尝试使用客户端的Firebase令牌发送通知/消息时,遇到了错误,例如发送者ID不匹配和HTTP状态为401的身份验证错误。请注意,使用Firebase控制台,我可以将消息发送到客户端。 对于客户端应用程序,我执行了以下操作: 从此处克隆了Firebase 快速入门应用程序-https : //github.com/firebase/qu

    • 我已经试着调试Firebase推送通知相当长时间了,但没有得到任何运气。我相信我已经正确地设置了临时配置文件和APNs证书。当我不包含方法时 当应用程序从Firebase通知控制台发送时,它会在前台接收通知,因为它会被打印出来,但它不会在后台接收通知。

    • 我开始使用新的Google通知服务 。 多亏了这个代码https://github.com/Firebase/quickstart-android/Tree/master/messaging,我才能够从我的Firebase用户控制台向我的Android设备发送通知。 是否有任何API或方法可以在不使用Firebase控制台的情况下发送通知?我的意思是,例如,一个PHP API或类似的东西,从我自己

    • 使用更新的Firebase cloud messaging和swizzling方法,当我的应用程序前景化时,我能够成功地在我的应用程序委托中的方法中接收有效负载。但是,我没有收到任何类型的有效负载,并且当我的应用程序处于后台时,不会被调用,尽管api响应消息已成功发送(见下文) 以下是我发送给FCM api的请求,以触发推送通知 有FCM的回复 这是我的appDelegate代码 我在我的应用程序

    • 我们使用的是Firebase云消息。有时,当Android或iOS应用程序处于睡眠模式时,手机会收到相同(重复)的通知信息。对于设备标识,使用FIRInstanceID令牌。node.js上的一个外部服务器用于向Firebase服务发送通知。我们的服务器日志文件中没有出现重复的内容。

    • null 我遵循Xamarin的文档实现了这个功能。 然后一步一步地执行,直到下面的部分: 后台通知 我点击了Log Token按钮并收到了令牌。 null Firebase控制台显示消息为“完成”。 我错过了什么来解决这个问题?