【问题标题】:Send push notification from server to android device in Java用 Java 将推送通知从服务器发送到 android 设备
【发布时间】:2016-10-31 13:04:23
【问题描述】:

我正在努力使用新的 FCM...我以前使用过 FCM,现在我正在尝试 FCM...

我正在尝试将我的应用服务器的推送通知发送到 android 设备。

我想用标准的Java包,尽量不要用Vert.x,apache的httpClient等……

这是我的代码:

public void sendNotification(String messageBody)
{
    try
    {
        URL url = new URL("https://fcm.googleapis.com/fcm/send");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");

        String apiKey = "AI...wE";

        String credentials = "key=" + apiKey;
        //String basicAuth = "Basic " + Base64.getEncoder().encodeToString(credentials.getBytes());

        String basicAuth = "Basic " + new String(Base64.encodeBase64(credentials.getBytes()));

        conn.setRequestProperty ("Authorization", basicAuth);

        String notfnStr = "{\"body\": \"this is my body\", \"title\": \"this is my title\"}";
        String dataStr = "{\"key1\": \"value1\", \"key2\": \"value2\"}";

        String bodyStr = "{\"priority\": \"high\", \"to\": \"dFC8GW0N1Q8:APA91bHePPmC7QVV16LGnR6rqxwreHSv1GgawijZ_dZL9T70ZkiXIV8TW_ymAWkvFfXRiWJmtR_UGBXBv2iV2UhS8M-Tndw8sf8ZW6zIqfaiiVJao3G5HFbhqgA18ukNNtW_J7JaWkz8\", " +
                "\"notification\": " + notfnStr + ", \"data\": " + dataStr + "}";

        System.out.println("### input: " + bodyStr);

        OutputStream os = conn.getOutputStream();
        os.write(bodyStr.getBytes());
        os.flush();

        if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
            throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
        }

        BufferedReader br = new BufferedReader(new InputStreamReader(
                (conn.getInputStream())));

        String output;
        System.out.println("Output from Server .... \n");
        while ((output = br.readLine()) != null) {
            System.out.println(output);
        }

        conn.disconnect();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

我得到的响应码是401,表示未经授权...我猜是凭证格式错误...

json 字符串是有效的 json 格式,所以我不用费心使用 JSONObject。

对于字符串凭据,我尝试过 "key:" + apiKey;但仍然得到相同的结果。

apiKey 字符串是从我从 Google 的 Firebase 控制台下载的 google-services.json 复制的。

谷歌没有给出一个很好的例子......只是给了我这个:https://firebase.google.com/docs/cloud-messaging/downstream

如果有人知道怎么做,请回复。谢谢!!

【问题讨论】:

    标签: java android firebase firebase-cloud-messaging


    【解决方案1】:

    据我所知,不需要对凭据进行 base64 编码:

    String apiKey = "AI...wE";
    String credentials = "key=" + apiKey;
    conn.setRequestProperty ("Authorization", credentials);
    

    【讨论】:

      【解决方案2】:

      您提到您从 google-services.json 文件中获得了他的密钥。那将是您的 Android API 密钥,而不是发送 FCM 消息所需的服务器密钥。在 Firebase 控制台中,转到 Settings > Cloud Messaging > Server key 以获取用于发送 FCM 消息的 API 密钥。

      【讨论】:

      • 嗨。汤普森先生只是一个简单的问题。 @fkie4 还提到他从 Firebase 控制台下载了 google-services.json 文件。 Firebase 控制台不会自动在google-services.json 中提供对应的Server Key 吗?
      • 哈!它现在正在工作。谢谢!我使用了错误的 API 密钥……而且,没有使用 base64 编码。我使用 conn.setRequestProperty ("Authorization", "key=" + apiKey);谢谢@frank !!
      • Np。 @intj 不,服务器密钥不应该真正包含在客户端应用程序中或由客户端应用程序使用。
      【解决方案3】:

      在 JAVA 中使用 FCM 发送通知的完整示例

      public class FCMNotification {
      
          // Method to send Notifications from server to client end.
          public final static String AUTH_KEY_FCM = "API_KEY_HERE";
          public final static String API_URL_FCM = "https://fcm.googleapis.com/fcm/send";
      
          public static void pushFCMNotification(String DeviceIdKey) throws Exception {
      
              String authKey = AUTH_KEY_FCM; // You FCM AUTH key
              String FMCurl = API_URL_FCM;
      
              URL url = new URL(FMCurl);
              HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      
              conn.setUseCaches(false);
              conn.setDoInput(true);
              conn.setDoOutput(true);
      
              conn.setRequestMethod("POST");
              conn.setRequestProperty("Authorization", "key=" + authKey);
              conn.setRequestProperty("Content-Type", "application/json");
      
              JSONObject data = new JSONObject();
              data.put("to", DeviceIdKey.trim());
              JSONObject info = new JSONObject();
              info.put("title", "FCM Notificatoin Title"); // Notification title
              info.put("text", "Hello First Test notification"); // Notification body
              data.put("notification", info);
      
              OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
              wr.write(data.toString());
              wr.flush();
              wr.close();
      
              int responseCode = conn.getResponseCode();
              System.out.println("Response Code : " + responseCode);
      
              BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
              String inputLine;
              StringBuffer response = new StringBuffer();
      
              while ((inputLine = in.readLine()) != null) {
                  response.append(inputLine);
              }
              in.close();
      
          }
      
          @SuppressWarnings("static-access")
          public static void main(String[] args) throws Exception {
              FCMNotification.pushFCMNotification("USER_DEVICE_TOKEN");
          }
      }
      

      【讨论】:

      • 这太棒了。
      • 发现.. 将 registration_ids 更改为 添加 JSONArray
      • 无法将 Java 8 和 Gson 用于 JSON,仍然得到 401
      • 因为pushFCMNotification方法是静态的,所以不需要从FCMNotification创建一个实例我已经编辑了这个
      【解决方案4】:

      这是一个用于将通知从 java 发送到应用程序 android 的功能。此代码使用 JSONObject,您必须将此 jar 添加到项目构建路径中。

      注意:我使用 fcm

      import java.io.OutputStreamWriter;
      import java.net.HttpURLConnection;
      import java.net.URL;
      
      import org.json.JSONObject;
      
      public class FcmNotif {
      public final static String AUTH_KEY_FCM ="AIzB***********RFA";
      
      public final static String API_URL_FCM ="https://fcm.googleapis.com/fcm/send";
      
               // userDeviceIdKey is the device id you will query from your database
      
          public void pushFCMNotification(String userDeviceIdKey, String title, String message) throws Exception{
      
          String authKey = AUTH_KEY_FCM;   // You FCM AUTH key
          String FMCurl = API_URL_FCM;     
      
          URL url = new URL(FMCurl);
          HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      
          conn.setUseCaches(false);
          conn.setDoInput(true);
          conn.setDoOutput(true);
      
          conn.setRequestMethod("POST");
          conn.setRequestProperty("Authorization","key="+authKey);
          conn.setRequestProperty("Content-Type","application/json");
      
          JSONObject json = new JSONObject();
          json.put("to",userDeviceIdKey.trim());
          JSONObject info = new JSONObject();
          info.put("title", title); // Notification title
          info.put("body", message); // Notification body
          info.put("image", "https://lh6.googleusercontent.com/-sYITU_cFMVg/AAAAAAAAAAI/AAAAAAAAABM/JmQNdKRPSBg/photo.jpg");
          info.put("type", "message");
          json.put("data", info);
          System.out.println(json.toString());
      
          OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
          wr.write(json.toString());
          wr.flush();
          conn.getInputStream();
          }
          }
      

      祝你好运

      【讨论】:

      • 嗨,我收到 mismatchId 错误。 userDeviceIdKey 来自哪里?我正在使用从 VAPID REQUEST 收到的请求,它附带“endpoint”:“fcm.googleapis.com/fcm/send/<THIS IS WHAT I PASS>”,但它不起作用。你能帮助我们吗? Tnx!
      • 当您在手机中安装您的应用程序时,您会获得 userDeviceIDKey(Token),然后您可以将它存储在您的数据库中,当您要发送通知时选择它并在此函数中传递它。它工作正常。
      猜你喜欢
      • 2016-05-06
      • 2020-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多