Firebase Java Server 向所有设备发送推送通知

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37576705/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:27:56  来源:igfitidea点击:

Firebase Java Server to send push notification to all devices

javaandroidfirebaseserver

提问by user3907491

I am trying to send a Push notification to my android device with the new Firebase service. I registered and setup an app, also I put all the code needed to receive notification in the android app. Via the Firebase Console I can send a notification to my app and it is received and shown. Now I want to write a java standalone server, to send a notification to ALL devices. This is my current code:

我正在尝试使用新的 Firebase 服务向我的 android 设备发送推送通知。我注册并设置了一个应用程序,我还将接收通知所需的所有代码都放在了 android 应用程序中。通过 Firebase 控制台,我可以向我的应用发送通知,并接收并显示该通知。现在我想编写一个 java 独立服务器,向所有设备发送通知。这是我当前的代码:

final String apiKey = "I added my key here";
URL url = new URL("https://fcm.googleapis.com/fcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "key=" + apiKey);

conn.setDoOutput(true);

String input = "{\"notification\" : {\"title\" : \"Test\"}, \"to\":\"test\"}";

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

int responseCode = conn.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + input);
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();

// print result
System.out.println(response.toString());

And this is the result that I am getting back from their servers:

这是我从他们的服务器返回的结果:

{"multicast_id":6602141464107786356,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}

Unfortunately, simply removing the "to" tag doesn't work, I am getting a code 400 returned then. I read that I need to register the device, send the device id to the server and save it there and then loop over all registered devices on the server to send the message. Isn't there an easier way, to just send a message to all devices, just like in the console?

不幸的是,简单地删除“to”标签是行不通的,然后我收到了返回的代码 400。我读到我需要注册设备,将设备 ID 发送到服务器并将其保存在那里,然后遍历服务器上所有已注册的设备以发送消息。难道没有更简单的方法,就像在控制台中一样向所有设备发送消息?

Your help is really appreciated, since I have been trying to get this to work all day long =(

非常感谢您的帮助,因为我一整天都在努力让它工作=(

Regards, Dustin

问候, 达斯汀

采纳答案by Alexander N.

I don't believe this is possible. Instead, what I would suggest is register all devices to the same topic and then you can message all the devices at once. Here is the help documentation on this:

我不相信这是可能的。相反,我建议将所有设备注册到同一主题,然后您可以一次向所有设备发送消息。这是关于此的帮助文档:

Send Topic Messages from the Server

从服务器发送主题消息

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

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

回答by Aditya varale

Android client side code should be:

Android 客户端代码应该是:

//subscribe_topic with name "ALL"
FirebaseMessaging.getInstance().subscribeToTopic("ALL");    

Server side:

服务器端:

string json = "{\"to\": \"/topics/ALL\",\"data\": {\"message\": \"This is a Cloud Messaging Topic Message\",}}";

回答by Geucimar

This solution send Push notification to Firebase using Apache HttpClient:

此解决方案使用 Apache HttpClient 向 Firebase 发送推送通知:

HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost("https://fcm.googleapis.com/fcm/send");
post.setHeader("Content-type", "application/json");
post.setHeader("Authorization", "key=AIzaSyBSxxxxsXevRq0trDbA9mhnY_2jqMoeChA");

JSONObject message = new JSONObject();
message.put("to", "dBbB2BFT-VY:APA91bHrvgfXbZa-K5eg9vVdUkIsHbMxxxxxc8dBAvoH_3ZtaahVVeMXP7Bm0iera5s37ChHmAVh29P8aAVa8HF0I0goZKPYdGT6lNl4MXN0na7xbmvF25c4ZLl0JkCDm_saXb51Vrte");
message.put("priority", "high");

JSONObject notification = new JSONObject();
notification.put("title", "Java");
notification.put("body", "Notifica??o do Java");

message.put("notification", notification);

post.setEntity(new StringEntity(message.toString(), "UTF-8"));
HttpResponse response = client.execute(post);
System.out.println(response);
System.out.println(message);

回答by OWADVL

  @Autowired
AndroidPushNotificationsService androidPushNotificationsService;

@RequestMapping(value = "/send", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<String> send() {


    JSONObject body = new JSONObject();
    // JsonArray registration_ids = new JsonArray();
    // body.put("registration_ids", registration_ids);
    body.put("to", "xxxxxxxxxxxxxxxxxxxjPwZpLgLpji_");
    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);

    HttpEntity<String> request = new HttpEntity<>(body.toString());

    CompletableFuture<FirebaseResponse> pushNotification = androidPushNotificationsService.send(request);
    CompletableFuture.allOf(pushNotification).join();

    try {
        FirebaseResponse firebaseResponse = pushNotification.get();
        if (firebaseResponse.getSuccess() == 1) {
            log.info("push notification sent ok!");
        } else {
            log.error("error sending push notifications: " + firebaseResponse.toString());
        }
        return new ResponseEntity<>(firebaseResponse.toString(), HttpStatus.OK);

    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
    return new ResponseEntity<>("the push notification cannot be send.", HttpStatus.BAD_REQUEST);
}

you can get the classes from here: https://github.com/AndreiD/testingpushnotifications

您可以从这里获取课程:https: //github.com/AndreiD/testingpushnotifications

回答by Durgesh Kumar

your code is perfect just recheck the registration id of the user whom you are sending the notification. In place of touse the users device regid. It worked perfect for me.

您的代码是完美的,只需重新检查您发送通知的用户的注册 ID。代替to使用用户设备注册。它对我来说很完美。

回答by Rjz Satvara

Your JSON will be like this:

您的 JSON 将是这样的:

      {
      "registration_ids": [
                        "fcm token 1",
                        "fcm token 2",
                        "fcm token 3"
                    ],
      "data": {
                "message": "msg"
              },
      "notification": {
                "title": "App name",
                "text": " your msg"
            }
    }
      {
      "registration_ids": [
                        "fcm token 1",
                        "fcm token 2",
                        "fcm token 3"
                    ],
      "data": {
                "message": "msg"
              },
      "notification": {
                "title": "App name",
                "text": " your msg"
            }
    }
public void sendGroupPush(Context context, ArrayList tokenlist, String message) {
            String msg = message;
            String title = context.getString(R.string.app_name);
            JSONArray regId = null;
            JSONObject objData = null;
            JSONObject data = null;
            JSONObject notif = null;
            try {
                regId = new JSONArray();
                for (int i = 0; i < tokenlist.size(); i++) {
                    regId.put(tokenlist.get(i));
                }
                data = new JSONObject();
                data.put("message", message);
                notif = new JSONObject();
                notif.put("title", title);
                notif.put("text", msg);

                objData = new JSONObject();
                objData.put("registration_ids", regId);
                objData.put("data", data);
                objData.put("notification", notif);
                Log.e("!_@rj@_group_PASS:>", objData.toString());
            } catch (JSONException e) {
                e.printStackTrace();
            }

            JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, Constants.FCM_PUSH_GROUP_URL, objData,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            Log.e("!_@rj@_@@_SUCESS", response + "");
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            Log.e("!_@rj@_@@_Errors--", error + "");
                        }
                    }) {
                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    Map<String, String> params = new HashMap<String, String>();
                    params.put("Authorization", "key=" + Constants.FCM_API_KEY);
                    params.put("Content-Type", "application/json");
                    Log.e("!_@rj@_@@PUSH_headrers", "::> " + params);
                    return params;
                }
            };
            RequestQueue requestQueue = Volley.newRequestQueue(context);
            int socketTimeout = 1000 * 60;// 60 seconds
            RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
            jsObjRequest.setRetryPolicy(policy);
            requestQueue.add(jsObjRequest);
        }

public static String FCM_PUSH_URL = "https://fcm.googleapis.com/fcm/send";

public static String FCM_PUSH_URL = " https://fcm.googleapis.com/fcm/send";

回答by Sandip S.

Use below code to send push notifications to multiple devices :

使用以下代码向多个设备发送推送通知:

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;

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

public static void sendPushNotification(List<String> deviceTokenList) {
    Sender sender = new Sender(AUTH_KEY_FCM);
    Message msg = new Message.Builder().addData("message", "Message body")
            .build();
    try {
        MulticastResult result = sender.send(msg, deviceTokenList, 5);
        for (Result r : result.getResults()) {
            if (r.getMessageId() != null) 
                System.out.println("Push Notification Sent Successfully");
             else 
                System.out.println("ErrorCode " + r.getErrorCodeName());
        }
    } catch (IOException e) {
        System.out.println("Error " + e.getLocalizedMessage());
    }
   }
  }   

Note : use gcm.server.jar

注意:使用 gcm.server.jar

回答by Arun-Khanka

Here I have very simple solution for sending push message group as well individual

在这里,我有非常简单的解决方案,用于发送推送消息组以及个人

public class FCM {
final static private String FCM_URL = "https://fcm.googleapis.com/fcm/send";

/**
* 
* Method to send push notification to Android FireBased Cloud messaging 
Server.
* @param tokenId Generated and provided from Android Client Developer
* @param server_key Key which is Generated in FCM Server 
   @param message which contains actual information.
* 
*/

static void send_FCM_Notification(String tokenId, String server_key, String 

message){


    try{
// Create URL instance.
URL url = new URL(FCM_URL);
// create connection.
HttpURLConnection conn;
conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
//set method as POST or GET
conn.setRequestMethod("POST");
//pass FCM server key
conn.setRequestProperty("Authorization","key="+server_key);
//Specify Message Format
conn.setRequestProperty("Content-Type","application/json");
//Create JSON Object & pass value
 JSONObject infoJson = new JSONObject();

 infoJson.put("title","Alankit");
infoJson.put("body", message);

JSONObject json = new JSONObject();
json.put("to",tokenId.trim());
json.put("notification", infoJson);

System.out.println("json :" +json.toString());
System.out.println("infoJson :" +infoJson.toString());
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(json.toString());
wr.flush();
int status = 0;
if( null != conn ){
status = conn.getResponseCode();
}
if( status != 0){

if( status == 200 ){
//SUCCESS message
BufferedReader reader = new BufferedReader(new 
InputStreamReader(conn.getInputStream()));
System.out.println("Android Notification Response : " + reader.readLine());
}else if(status == 401){
//client side error
System.out.println("Notification Response : TokenId : " + tokenId + " Error occurred :");
}else if(status == 501){
//server side error
System.out.println("Notification Response : [ errorCode=ServerError ] TokenId : " + tokenId);
}else if( status == 503){
//server side error
System.out.println("Notification Response : FCM Service is Unavailable  
TokenId : " + tokenId);
}
}
}catch(MalformedURLException mlfexception){
// Prototcal Error
System.out.println("Error occurred while sending push Notification!.." + mlfexception.getMessage());
}catch(Exception mlfexception){
//URL problem
System.out.println("Reading URL, Error occurred while sending push 
Notification!.." + mlfexception.getMessage());
}

}

 static void send_FCM_NotificationMulti(List<String> putIds2, String 
tokenId, 
 String server_key, String message){
    try{
    // Create URL instance.
    URL url = new URL(FCM_URL);
    // create connection.
    HttpURLConnection conn;
    conn = (HttpURLConnection) url.openConnection();
    conn.setUseCaches(false);
    conn.setDoInput(true);
    conn.setDoOutput(true);
    //set method as POST or GET
    conn.setRequestMethod("POST");
    //pass FCM server key
    conn.setRequestProperty("Authorization","key="+server_key);
    //Specify Message Format
    conn.setRequestProperty("Content-Type","application/json");
    //Create JSON Object & pass value

        JSONArray regId = null;
        JSONObject objData = null;
        JSONObject data = null;
        JSONObject notif = null;

            regId = new JSONArray();
            for (int i = 0; i < putIds2.size(); i++) {
                regId.put(putIds2.get(i));
            }
            data = new JSONObject();
            data.put("message", message);
            notif = new JSONObject();
            notif.put("title", "Alankit Universe");
            notif.put("text", message);

            objData = new JSONObject();
            objData.put("registration_ids", regId);
            objData.put("data", data);
            objData.put("notification", notif);
            System.out.println("!_@rj@_group_PASS:>"+ objData.toString());


    System.out.println("json :" +objData.toString());
    OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());

    wr.write(objData.toString());
    wr.flush();
    int status = 0;
    if( null != conn ){
    status = conn.getResponseCode();
    }
    if( status != 0){

        if( status == 200 ){
    //SUCCESS message
    BufferedReader reader = new BufferedReader(new 
    InputStreamReader(conn.getInputStream()));
    System.out.println("Android Notification Response : " + 
    reader.readLine());
    }else if(status == 401){
    //client side error
    System.out.println("Notification Response : TokenId : " + tokenId + " 
      Error occurred :");
    }else if(status == 501){
    //server side error
    System.out.println("Notification Response : [ errorCode=ServerError ] 
    TokenId : " + tokenId);
    }else if( status == 503){
    //server side error
    System.out.println("Notification Response : FCM Service is Unavailable  
   TokenId : " + tokenId);
    }
    }
    }catch(MalformedURLException mlfexception){
    // Prototcal Error
    System.out.println("Error occurred while sending push Notification!.." + 
   mlfexception.getMessage());
    }catch(IOException mlfexception){
    //URL problem
    System.out.println("Reading URL, Error occurred while sending push 
  Notification!.." + mlfexception.getMessage());
    }catch (Exception exception) {
    //General Error or exception.
    System.out.println("Error occurred while sending push Notification!.." + 
 exception.getMessage());
    }

    }

}

}

     Calling should be like that :



  public class TestFCM {
        static List<String> putIds;
        public static void main(String[] args) {

    //Just I am passed dummy information
    // DeviceID's

    String tokenId1 = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    String tokenId  = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
    String server_key ="<Server Key>" ;
    String message = "Welcome alankit Push Service.";

    putIds= new ArrayList<>();
    putIds.add(tokenId1);
    putIds.add(tokenId);

   /* for Group*/
    FCM.send_FCM_NotificationMulti(putIds,tokenId,server_key,message);  

    /*for indevidual*/
    FCM.send_FCM_Notification( tokenId,server_key,message);
    }


}

回答by Developine

All you need is Firebase Server Key for authorization purpose. You just have to write http client code, you can use any programming language for that purpose.

您只需要用于授权目的的 Firebase 服务器密钥。您只需要编写 http 客户端代码,您可以为此使用任何编程语言。

Check out this Github Repo. It has complete Java Rest Client project for sending firebase push notification from java server.

看看这个Github Repo。它有完整的 Java Rest Client 项目,用于从 Java 服务器发送 Firebase 推送通知。

回答by Mandeep Singh

The Use the below code to send push to multiple devices using FCM.

使用以下代码使用 FCM 向多个设备发送推送。

public void sendAndroidPush(String input) {
        final String apiKey = ServerKey or legacyServerKey;
        StringBuffer response = new StringBuffer();
        try {
            URL url = new URL("https://fcm.googleapis.com/fcm/send");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setRequestProperty("Authorization", "key=" + apiKey);

            conn.setDoOutput(true);

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

            int responseCode = conn.getResponseCode();
            System.out.println("\nSending 'POST' request to URL : " + url);
            System.out.println("Post parameters : " + input);
            System.out.println("Response Code : " + responseCode);

            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String inputLine;


            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
        // print result
        System.out.println(response.toString());
    }


JSONArray devices = new JSONArray();
        devices.put("Your Actual Device Token");

        JSONObject payloadObj = new JSONObject();
        try {
            JSONObject notifyObj = new JSONObject();
            notifyObj.put("title","Your Title");
            notifyObj.put("text", "Your Text");

            payloadObj.put("registration_ids",devices.toString());
            payloadObj.put("notification",notifyObj.toString());

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        sendAndroidPush(payloadObj.toString());