使用FCM从服务器发送推送通知

39

最近我在Stack Overflow上提出了一个关于使用GCM发送推送通知的问题:Send push notifications to Android。现在有了FCM,我想知道在服务器端开发方面,它与GCM有何不同?从编码方面来说,它们是相同的吗?在哪里可以找到示例FCM代码,以向Android设备发送推送通知?

在使用Java代码发送通知到FCM时,我是否需要下载任何JAR库?在发送推送通知至Android的示例代码中显示了使用GCM发送推送通知,并且需要一个服务器端GCM JAR文件。

然而,在https://www.quora.com/How-do-I-make-a-post-request-to-a-GCM-server-in-Java-to-push-a-notification-to-the-client-app的另一个示例中,使用GCM发送推送通知,不需要服务器端GCM JAR文件,因为它仅通过HTTP连接进行发送。同样的代码是否适用于FCM?所使用的URL为“https://android.googleapis.com/gcm/send”。FCM的等效URL是什么?


你是否访问过 FCM 网站?网站上提供了一步一步的方法,可以将你当前的 GCM 项目转换为 FCM。 - MNM
我目前还没有任何推送通知的代码,例如GCM。我仍在研究推送通知背后的技术。 - user3573403
阅读此博客文章以获取更多详细信息。http://developine.com/how-to-send-firebase-push-notifications-from-app-server-tutorial/ - Developine
6个回答

35

服务器端编程和客户端编程有什么不同?

由于差别并不大,您可以查看大多数用于GCM的示例服务器端代码。与GCM相比,FCM的主要区别在于,当使用FCM时,您可以使用其中的新特性(如此答案中所提到的)。 FCM还有一个控制台,您可以从中发送消息/通知,而无需拥有自己的应用程序服务器。

注意:创建自己的应用程序服务器取决于您自己。只是说明您可以通过控制台发送消息/通知。

使用的URL为“https://android.googleapis.com/gcm/send”。FCM的等效URL是什么?

FCM的等效URL为https://fcm.googleapis.com/fcm/send。您可以查看文档以获取更多详细信息。
干杯! :D

1
嗨,McAwesomville,感谢您的回复。看起来我们在使用GCM或FCM发送通知时不需要额外的库JAR文件。我们只需向GCM / FCM服务器发送所需数据的HTTP POST即可。 - user3573403
1
是的,不需要JAR文件。我在回答中忘记包含它了。干杯! - AL.
大家可以阅读这篇博客文章获取更多细节信息:http://developine.com/how-to-send-firebase-push-notifications-from-app-server-tutorial/ - Developine
如果我的服务器指向 FCM 端点(GCM 云项目未转换为 Firebase 项目),但推送使用旧的 GCM API 密钥,那么旧的客户端应用程序推送仍然可以正常工作,对吗? - Chris Ho
我们如何在发送/推送通知的HTTP请求中发送channel_id?请提供建议。谢谢。 - Kamlesh

23

使用以下代码从 FCM 服务器发送推送通知:

public class PushNotifictionHelper {
    public final static String AUTH_KEY_FCM = "Your api key";
    public final static String API_URL_FCM = "https://fcm.googleapis.com/fcm/send";

    public static String sendPushNotification(String deviceToken)
            throws IOException {
        String result = "";
        URL url = new URL(API_URL_FCM);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        conn.setUseCaches(false);
        conn.setDoInput(true);
        conn.setDoOutput(true);

        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "key=" + AUTH_KEY_FCM);
        conn.setRequestProperty("Content-Type", "application/json");

        JSONObject json = new JSONObject();

        json.put("to", deviceToken.trim());
        JSONObject info = new JSONObject();
        info.put("title", "notification title"); // Notification title
        info.put("body", "message body"); // Notification
                                                                // body
        json.put("notification", info);
        try {
            OutputStreamWriter wr = new OutputStreamWriter(
                    conn.getOutputStream());
            wr.write(json.toString());
            wr.flush();

            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);
            }
            result = CommonConstants.SUCCESS;
        } catch (Exception e) {
            e.printStackTrace();
            result = CommonConstants.FAILURE;
        }
        System.out.println("GCM Notification is sent successfully");

        return result;

}

Sandip先生,这个工作得很好,谢谢您,我有一些问题,为什么您在这里使用OutputStreamWriter? - Vasantha Raj

1

完整的主题、单个设备和多个设备的解决方案 创建一个名为 FireMessage 的类。这是数据消息的示例。您可以将数据更改为通知。

public class FireMessage {
private final String SERVER_KEY = "YOUR SERVER KEY";
private final String API_URL_FCM = "https://fcm.googleapis.com/fcm/send";
private JSONObject root;

public FireMessage(String title, String message) throws JSONException {
    root = new JSONObject();
    JSONObject data = new JSONObject();
    data.put("title", title);
    data.put("message", message);
    root.put("data", data);
}


public String sendToTopic(String topic) throws Exception { //SEND TO TOPIC
    System.out.println("Send to Topic");
    root.put("condition", "'"+topic+"' in topics");
    return sendPushNotification(true);
}

public String sendToGroup(JSONArray mobileTokens) throws Exception { // SEND TO GROUP OF PHONES - ARRAY OF TOKENS
    root.put("registration_ids", mobileTokens);
    return sendPushNotification(false);
}

public String sendToToken(String token) throws Exception {//SEND MESSAGE TO SINGLE MOBILE - TO TOKEN
    root.put("to", token);
    return sendPushNotification(false);
}



    private String sendPushNotification(boolean toTopic)  throws Exception {
        URL url = new URL(API_URL_FCM);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        conn.setUseCaches(false);
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");

        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Accept", "application/json");
        conn.setRequestProperty("Authorization", "key=" + SERVER_KEY);

        System.out.println(root.toString());

        try {
            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
            wr.write(root.toString());
            wr.flush();

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

            String output;
            StringBuilder builder = new StringBuilder();
            while ((output = br.readLine()) != null) {
                builder.append(output);
            }
            System.out.println(builder);
            String result = builder.toString();

            JSONObject obj = new JSONObject(result);

            if(toTopic){
                if(obj.has("message_id")){
                    return  "SUCCESS";
                }
           } else {
            int success = Integer.parseInt(obj.getString("success"));
            if (success > 0) {
                return "SUCCESS";
            }
        }

            return builder.toString();
        } catch (Exception e) {
            e.printStackTrace();
           return e.getMessage();
        }

    }

}

我们可以像这样随时随地进行调用,无论是服务器还是Android设备都可以使用此功能。

FireMessage f = new FireMessage("MY TITLE", "TEST MESSAGE");

      //TO SINGLE DEVICE
    /*  String fireBaseToken="c2N_8u1leLY:APA91bFBNFYDARLWC74QmCwziX-YQ68dKLNRyVjE6_sg3zs-dPQRdl1QU9X6p8SkYNN4Zl7y-yxBX5uU0KEKJlam7t7MiKkPErH39iyiHcgBvazffnm6BsKjRCsKf70DE5tS9rIp_HCk";
       f.sendToToken(fireBaseToken); */

    // TO MULTIPLE DEVICE
    /*  JSONArray tokens = new JSONArray();
      tokens.put("c2N_8u1leLY:APA91bFBNFYDARLWC74QmCwziX-YQ68dKLNRyVjE6_sg3zs-dPQRdl1QU9X6p8SkYNN4Zl7y-yxBX5uU0KEKJlam7t7MiKkPErH39iyiHcgBvazffnm6BsKjRCsKf70DE5tS9rIp_HCk");
      tokens.put("c2R_8u1leLY:APA91bFBNFYDARLWC74QmCwziX-YQ68dKLNRyVjE6_sg3zs-dPQRdl1QU9X6p8SkYNN4Zl7y-yxBX5uU0KEKJlam7t7MiKkPErH39iyiHcgBvazffnm6BsKjRCsKf70DE5tS9rIp_HCk");
       f.sendToGroup(tokens);  */

    //TO TOPIC
      String topic="yourTopicName";
       f.sendToTopic(topic); 

1
这是来自Google的消息:

您无需对升级进行任何服务器端协议更改。服务协议未更改。但请注意,所有新的服务器增强功能将记录在 FCM 服务器文档中。

从接收消息的角度来看,似乎只有一些地方略有不同。主要是删除一些内容。
FCM 服务器文档可以在此处找到: https://firebase.google.com/docs/cloud-messaging/server

0

我已经为FCM通知服务器创建了一个库。只需像使用GCM库一样使用它。

对于FCM服务器,请使用以下代码:

GCM服务器URL-"android.googleapis.com/gcm/send"

FCM服务器URL - "fcm.googleapis.com/fcm/send"

在URL后附加https

Sender objSender = new Sender(gAPIKey);

或者

Sender objSender = new Sender(gAPIKey,"SERVER_URL");

默认情况下,FCM服务器URL已分配。

Message objMessage = new Message.Builder().collapseKey("From FCMServer").timeToLive(3).delayWhileIdle(false)
                .notification(notification)
                .addData("ShortMessage", "Sh").addData("LongMessage", "Long ")
                .build();
        objMulticastResult = objSender.send(objMessage,clientId, 4);
  • 这个库的依赖需求与GCM lib所需的(jsonsimple.jar)相同。

  • FCM_Server.jar下载lib。


你能将它发布到Maven吗? - f.khantsis

0
public class SendPushNotification extends AsyncTask<Void, Void, Void> {

    private final String FIREBASE_URL = "https://fcm.googleapis.com/fcm/send";
    private final String SERVER_KEY = "REPLACE_YOUR_SERVER_KEY";
    private Context context;
    private String token;

    public SendPushNotification(Context context, String token) {
        this.context = context;
        this.token = token;
    }

    @Override
    protected Void doInBackground(Void... voids) {

        /*{
            "to": "DEVICE_TOKEN",
            "data": {
            "type": "type",
                "title": "Android",
                "message": "Push Notification",
                "data": {
                    "key": "Extra data"
                }
            }
        }*/

        try {
            URL url = new URL(FIREBASE_URL);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);

            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Accept", "application/json");
            connection.setRequestProperty("Authorization", "key=" + SERVER_KEY);

            JSONObject root = new JSONObject();
            root.put("to", token);

            JSONObject data = new JSONObject();
            data.put("type", "type");
            data.put("title", "Android");
            data.put("message", "Push Notification");

            JSONObject innerData = new JSONObject();
            innerData.put("key", "Extra data");

            data.put("data", innerData);
            root.put("data", data);
            Log.e("PushNotification", "Data Format: " + root.toString());

            try {
                OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
                writer.write(root.toString());
                writer.flush();
                writer.close();

                int responseCode = connection.getResponseCode();
                Log.e("PushNotification", "Request Code: " + responseCode);

                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader((connection.getInputStream())));
                String output;
                StringBuilder builder = new StringBuilder();
                while ((output = bufferedReader.readLine()) != null) {
                    builder.append(output);
                }
                bufferedReader.close();
                String result = builder.toString();
                Log.e("PushNotification", "Result JSON: " + result);
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("PushNotification", "Error: " + e.getMessage());
            }

        } catch (Exception e) {
            e.printStackTrace();
            Log.e("PushNotification", "Error: " + e.getMessage());
        }

        return null;
    }
}

用法

SendPushNotification sendPushNotification = new SendPushNotification(context, "token");
sendPushNotification.execute();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接