Как отправлять сообщения с устройства на устройство с помощью Firebase Cloud Messaging?

#ionic-framework #firebase #firebase-cloud-messaging

#firebase #firebase-cloud-messaging

Вопрос:

После поиска в документах я не смог найти никакой информации о том, как отправлять сообщения с устройства на устройство с помощью FCM без использования внешнего сервера.

Например, если бы я создавал приложение для чата, мне нужно было бы отправлять пользователям push-уведомления о непрочитанных сообщениях, поскольку они не будут постоянно подключены к сети, и я не могу иметь постоянную службу в фоновом режиме, которая всегда была бы подключена к базе данных реального времени, потому что это было бы слишком ресурсоемко.

Итак, как мне отправить push-уведомление пользователю «A», когда определенный пользователь «B» отправляет ему / ей сообщение чата? Нужен ли мне для этого внешний сервер или это можно сделать только с помощью серверов Firebase?

Комментарии:

1. Я еще не использовал FCM …. но я использовал GCM …. предполагая, что FCM почти как GCM ….. устройство A отправляет сообщение серверу, который отправит сообщение на устройство B. Ознакомьтесь firebase.google.com/support/faq/#messaging-difference

2. @j4rey89 Да, я знаю, что это можно сделать с помощью внешнего сервера. Я спрашиваю, можно ли обойтись без этого, поскольку это потребовало бы от меня обслуживания и оплаты двух серверов вместо одного.

3. @Suyash для отправки сообщений FCM между вашими устройствами обязательно запустить свой собственный сервер. Если вас беспокоят затраты на эксплуатацию сервера, вы можете начать развертывание с Openshift Online (PaaS) или Google AppEngine (тоже PaaS), у которых есть бесплатная квота.

4. @j4rey89 MrBrightside: звучит как ответ. 🙂

5. Смотрите: firebase.googleblog.com/2016/08 /…

Ответ №1:

ОБНОВЛЕНИЕ: Теперь можно использовать функции firebase cloud в качестве сервера для обработки push-уведомлений. Ознакомьтесь с их документацией здесь

============

Согласно документам, вы должны внедрить сервер для обработки push-уведомлений при обмене сообщениями между устройствами.

Прежде чем вы сможете писать клиентские приложения, использующие Firebase Cloud Messaging, у вас должен быть сервер приложений, соответствующий следующим критериям:

Вам нужно решить, какие протоколы сервера соединений FCM вы хотите использовать, чтобы ваш сервер приложений мог взаимодействовать с серверами соединений FCM. Обратите внимание, что если вы хотите использовать восходящий обмен сообщениями из своих клиентских приложений, вы должны использовать XMPP. Более подробное обсуждение этого см. в разделе Выбор протокола сервера подключения FCM.

Если вам нужно отправлять пользователям только базовые уведомления с сервера. Вы можете использовать их бессерверное решение, Firebase Notifications.

Смотрите сравнение здесь между уведомлениями FCM и Firebase:https://firebase.google.com/support/faq/#messaging-difference

Комментарии:

1. хороший ответ. Знаете ли вы какие-либо учебные пособия или видео, которые могут объяснить, как это сделать? Спасибо

2. Смотрите firebase.googleblog.com/2016/08/…

3. Не могли бы вы помочь мне понять, пожалуйста. Насколько я понимаю, если мне нужно отправить прямое сообщение от одного пользователя к другому, я должен использовать HTTP и отправить это сообщение на свой сервер, а следующий сервер будет использовать FCM для отправки уведомления получателю и, таким образом, получатель получит данные с идентификатором отправителя. Следующим шагом получатель подключается к FCM и с помощью ID извлекает все данные из базы данных FCM? Таким способом?

4. Идеальный ответ, я исследовал ab за эти 2 дня. Очень полная информация о FCM и необходимости разделения или нет. Спасибо!.

Ответ №2:

Выполнение HTTP POST запроса со ссылкойhttps://fcm.googleapis.com/fcm/send мне помогли требуемый заголовок и данные. В приведенном ниже фрагменте кода Constants.LEGACY_SERVER_KEY указана переменная локального класса, вы можете найти ее в своем проекте Firebase Settings->Cloud Messaging->Legacy Server key . Вам необходимо передать маркер регистрации устройства, т.Е. regToken в приведенном ниже фрагменте кода, на который есть ссылка ЗДЕСЬ.

Наконец, вам нужна зависимость от библиотеки okhttp, чтобы заставить этот фрагмент работать.

 public static final MediaType JSON
        = MediaType.parse("application/json; charset=utf-8");
private void sendNotification(final String regToken) {
    new AsyncTask<Void,Void,Void>(){
        @Override
        protected Void doInBackground(Void... params) {
            try {
                OkHttpClient client = new OkHttpClient();
                JSONObject json=new JSONObject();
                JSONObject dataJson=new JSONObject();
                dataJson.put("body","Hi this is sent from device to device");
                dataJson.put("title","dummy title");
                json.put("notification",dataJson);
                json.put("to",regToken);
                RequestBody body = RequestBody.create(JSON, json.toString());
                Request request = new Request.Builder()
                        .header("Authorization","key=" Constants.LEGACY_SERVER_KEY)
                        .url("https://fcm.googleapis.com/fcm/send")
                        .post(body)
                        .build();
                Response response = client.newCall(request).execute();
                String finalResponse = response.body().string();
            }catch (Exception e){
                //Log.d(TAG,e "");
            }
            return null;
        }
    }.execute();

}
  

далее, если вы хотите отправить сообщение в определенную тему, замените regToken в json следующим образом

 json.put("to","/topics/foo-bar")
  

и не забудьте добавить разрешение на доступ в Интернет в вашем AndroidManifest.xml .

ВАЖНО: — Использование приведенного выше кода означает, что ключ вашего сервера находится в клиентском приложении. Это опасно, поскольку кто-то может проникнуть в ваше приложение и получить ключ сервера для отправки вредоносных уведомлений вашим пользователям.

Комментарии:

1. Привет, есть ли какая-либо возможность отправлять сообщения на определенный подписанный канал?

2. Недостатком является то, что ваш серверный ключ находится в клиентском приложении. Это опасно, поскольку кто-то может проникнуть в ваше приложение и получить ключ сервера для отправки вредоносных уведомлений вашим пользователям. Вот почему вы никогда не должны этого делать.

3. @kirtan403 Надежное шифрование ключа сервера на стороне клиента может остановить это???

4. @Mr.Popular Возможно, но если кто-то способен декомпилировать ваш код (конечно, он может), то он может захватить то, что вы используете для шифрования вашего серверного ключа, и получить ваш серверный ключ. И тогда они могут отправлять уведомления кому угодно без каких-либо ограничений.. Поэтому очень плохая идея помещать ключ сервера на стороне клиента. Очень, очень плохая идея…

5. @Tabish пожалуйста, используйте remoteMessage.getNotification(). Мы не отправляем данные здесь.

Ответ №3:

Вы можете сделать это с помощью запроса Volly Jsonobject….

сначала выполните следующие действия:

1 скопируйте устаревший ключ сервера и сохраните его как Legacy_SERVER_KEY

Устаревший ключ сервера

вы можете видеть на рисунке, как получить

2 Вам нужна зависимость от Volley

скомпилируйте ‘com.mcxiaoke.volley:библиотека:1.0.19’

введите описание изображения здесь

Код для отправки Push:-

 private void sendFCMPush() {

    String Legacy_SERVER_KEY = YOUR_Legacy_SERVER_KEY;
    String msg = "this is test message,.,,.,.";
    String title = "my title";
    String token = FCM_RECEIVER_TOKEN;

    JSONObject obj = null;
    JSONObject objData = null;
    JSONObject dataobjData = null;

    try {
        obj = new JSONObject();
        objData = new JSONObject();

        objData.put("body", msg);
        objData.put("title", title);
        objData.put("sound", "default");
        objData.put("icon", "icon_name"); //   icon_name image must be there in drawable
        objData.put("tag", token);
        objData.put("priority", "high");

        dataobjData = new JSONObject();
        dataobjData.put("text", msg);
        dataobjData.put("title", title);

        obj.put("to", token);
        //obj.put("priority", "high");

        obj.put("notification", objData);
        obj.put("data", dataobjData);
        Log.e("!_@rj@_@@_PASS:>", obj.toString());
    } catch (JSONException e) {
        e.printStackTrace();
    }

    JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, Constants.FCM_PUSH_URL, obj,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.e("!_@@_SUCESS", response   "");
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("!_@@_Errors--", error   "");
                }
            }) {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("Authorization", "key="   Legacy_SERVER_KEY);
            params.put("Content-Type", "application/json");
            return params;
        }
    };
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    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);
}
  

Просто вызовите sendFCMPush ();

Комментарии:

1. Привет, есть ли какая-либо возможность отправлять сообщения на определенный подписанный канал?

2. да, возможно, вам нужно добавить для этого флаг, и в зависимости от этого вы можете отправлять Push подписанным пользователям

3. @RjzSatvara что делать, если приложение не запущено на телефоне-получателе? получит ли оно сообщение? Заранее спасибо

4. @Jaco , для этого нет возможности. вы должны управлять этим другим способом.

Ответ №4:

1) подписаться под идентичным названием темы, например:

  • ClientA.subscribe(«to/topic_users_channel»)
  • ClientB.subscribe(«to/topic_users_channel»)

2) отправлять сообщения внутри приложения

GoogleFirebase: как отправлять тематические сообщения

Комментарии:

1. Не потребует ли это по-прежнему использования ключа авторизации на стороне клиента? Что делает его небезопасным. Также я даже не знаю, является ли хорошей идеей создание отдельной темы для каждого пользователя.

2. Хорошая идея, но: тематические сообщения оптимизированы для пропускной способности, а не для задержки. Для быстрой и безопасной доставки на отдельные устройства или небольшие группы устройств направляйте сообщения на регистрационные маркеры, а не на темы.

3. @Maxim Firsoff — Как создать тему из консоли FCM или любым другим способом?

4. @AjaySharma насколько я помню, в консоли FMC для этого нет инструментов, вы можете создать тему программно (см. Мой псевдокод выше).

Ответ №5:

Да, это возможно сделать без какого-либо сервера. Вы можете создать группу устройств на стороне клиента, а затем обмениваться сообщениями в группе. Однако существуют ограничения:

  1. Вы должны использовать одну и ту же учетную запись Google на устройствах
  2. Вы не можете отправлять сообщения с высоким приоритетом

Ссылка: Документ Firebase Смотрите в разделе «Управление группами устройств в клиентских приложениях Android»

Комментарии:

1. вам все еще нужен сервер для отправки группового сообщения

2. Ни в коем случае. Любое устройство в группе может отправить сообщение

3. из документов: Авторизация: ключ = API_KEY Вам все еще нужен ключ сервера. таким образом, это решение не подходит для производства

4. Ключом API является учетная запись Google, и общение ограничено учетной записью одного пользователя. Попробуйте, прежде чем комментировать.

Ответ №6:

Облачные функции Google теперь позволяют отправлять push-уведомления с устройства на устройство без сервера приложений. Я создал облачную функцию, которая запускается при добавлении нового сообщения в базу данных

Это node.js код

 'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin'); admin.initializeApp();

exports.sendNotification = functions.database.ref('/conversations/{chatLocation}/{messageLocation}')
  .onCreate((snapshot, context) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = snapshot.val();

       const toIDUser = original.toID;
       const isGroupChat = original.isGroupChat;

       if (isGroupChat) {
       const tokenss =  admin.database().ref(`/users/${toIDUser}/tokens`).once('value').then(function(snapshot) {

// Handle Promise
       const tokenOfGroup = snapshot.val()

      // get tokens from the database  at particular location get values 
       const valuess = Object.keys(tokenOfGroup).map(k => tokenOfGroup[k]);

     //console.log(' ____________ddd((999999ddd_________________ '    valuess );
    const payload = {
       notification: {
                 title:   original.senderName   " :- ",
                 body:    original.content
    }
  };

  return admin.messaging().sendToDevice(valuess, payload);



}, function(error) {

  console.error(error);
});

       return ;
          } else {
          // get token from the database  at particular location
                const tokenss =  admin.database().ref(`/users/${toIDUser}/credentials`).once('value').then(function(snapshot) {
                // Handle Promise
  // The Promise was "fulfilled" (it succeeded).

     const credentials = snapshot.val()



    // console.log('snapshot ......snapshot.val().name****^^^^^^^^^^^^kensPromise****** :- ', credentials.name);
     //console.log('snapshot.....****snapshot.val().token****^^^^^^^^^^^^kensPromise****** :- ', credentials.token);


     const deviceToken = credentials.token;

    const payload = {
       notification: {
                 title:   original.senderName   " :- ",
                 body:    original.content
    }
  };

  return admin.messaging().sendToDevice(deviceToken, payload);


}, function(error) {

  console.error(error);
});


          }





  return ;


    });
  

Ответ №7:

Облачные функции Google теперь позволяют отправлять push-уведомления с устройства на устройство без сервера приложений.

С соответствующей страницы облачных функций Google:

Разработчики могут использовать облачные функции, чтобы поддерживать активность пользователей и получать актуальную информацию о приложении. Рассмотрим, например, приложение, которое позволяет пользователям следить за действиями друг друга в приложении. В таком приложении функция, запускаемая при записи в базу данных в реальном времени для сохранения новых подписчиков, может создавать уведомления Firebase Cloud Messaging (FCM), чтобы соответствующие пользователи знали, что у них появились новые подписчики.

Пример:

  1. Функция запускает запись в базу данных реального времени path, где хранятся подписчики.

  2. Функция создает сообщение для отправки через FCM.

  3. FCM отправляет уведомление на устройство пользователя.

Вот демонстрационный проект для отправки push-уведомлений с устройства на устройство с функциями Firebase и Google Cloud.

Ответ №8:

Для этого вы можете использовать firebase realtime database. Вы можете создать структуру данных для хранения чатов и добавить наблюдателей для потоков беседы для обоих пользователей. Он по-прежнему использует архитектуру устройство — сервер — устройство, но в этом случае со стороны разработчиков нет дополнительного сервера. При этом используются серверы firebase. Вы можете ознакомиться с руководством здесь (игнорируйте часть пользовательского интерфейса, хотя это также хорошая отправная точка для фреймворков пользовательского интерфейса чата).

Чат Firebase в реальном времени

Комментарии:

1. Пользователь не будет постоянно использовать приложение, и мы не можем использовать firebase realtime database в фоновом режиме, поскольку она поддерживает постоянное сокет-соединение с сервером, что слишком сильно нагружает батарею устройства.

2. Я могу отправлять сообщения Firebase между устройствами и уведомления, используя библиотеку Smack. Я не реализую какой-либо внешний сервер в своем коде Android. Smack управляет соединением и входящими / исходящими разделами сообщений, используя протокол XMPP.

Ответ №9:

Если у вас есть токен fcm (gcm) устройства, которому вы хотите отправить уведомление. Это просто post-запрос на отправку уведомления.

https://github.com/prashanthd/google-services/blob/master/android/gcm/gcmsender/src/main/java/gcm/play/android/samples/com/gcmsender/GcmSender.java

Комментарии:

1. Да, но для этого все еще требуется наш собственный внешний сервер, верно? Потому что мы не должны внедрять API_KEY непосредственно в наших клиентах. Мой вопрос заключался в том, возможно ли это без внешнего сервера, который в настоящее время не соответствует предложениям других ответов.

Ответ №10:

В моем случае я использую модификацию с этим классом Message:

 public class Message {

    private String to;
    private String collapseKey;
    private Notification notification;
    private Data data;

    public Message(String to, String collapseKey, Notification notification, Data data) {
        this.to = to;
        this.collapseKey = collapseKey;
        this.notification = notification;
        this.data = data;
    }
}
  

Данные

 public class Data {

    private String body;
    private String title;
    private String key1;
    private String key2;

    public Data(String body, String title, String key1, String key2) {
        this.body = body;
        this.title = title;
        this.key1 = key1;
        this.key2 = key2;
    }
}
  

Уведомление

 public class Notification {

    private String body;
    private String title;

    public Notification(String body, String title) {
        this.body = body;
        this.title = title;
    }
}
  

этот вызов

 private void sentToNotification() {
    String to = "YOUR_TOKEN";
    String collapseKey = "";
    Notification notification = new Notification("Hello bro", "title23");
    Data data = new Data("Hello2", "title2", "key1", "key2");
    Message notificationTask = new Message(to, collapseKey, notification, data);

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://fcm.googleapis.com/")//url of FCM message server
            .addConverterFactory(GsonConverterFactory.create())//use for convert JSON file into object
            .build();

    ServiceAPI api = new retrofit.create(ServiceAPI.class);

    Call<Message> call = api .sendMessage("key=YOUR_KEY", notificationTask);

    call.enqueue(new Callback<Message>() {
        @Override
        public void onResponse(Call<Message> call, retrofit2.Response<Message> response) {
            Log.d("TAG", response.body().toString());
        }

        @Override
        public void onFailure(Call<Message> call, Throwable t) {

            Log.e("TAG", t.getMessage());
        }
    });
}
  

наш ServiceAPi

 public interface ServiceAPI {
    @POST("/fcm/send")
    Call<Message> sendMessage(@Header("Authorization") String token, @Body Message message);
}
  

Ответ №11:

Вы можете использовать Retrofit. Подпишите устройства на тематические новости. Отправлять уведомления с одного устройства на другое.

 public void onClick(View view) {

    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    httpClient.addInterceptor(new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request original = chain.request();

            // Request customization: add request headers
            Request.Builder requestBuilder = original.newBuilder()
                    .header("Authorization", "key=legacy server key from FB console"); // <-- this is the important line
            Request request = requestBuilder.build();
            return chain.proceed(request);
        }
    });

    httpClient.addInterceptor(logging);
    OkHttpClient client = httpClient.build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://fcm.googleapis.com")//url of FCM message server
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())//use for convert JSON file into object
            .build();

    // prepare call in Retrofit 2.0
    FirebaseAPI firebaseAPI = retrofit.create(FirebaseAPI.class);

    //for messaging server
    NotifyData notifydata = new NotifyData("Notification title","Notification body");

    Call<Message> call2 = firebaseAPI.sendMessage(new Message("topic or deviceID", notifydata));

    call2.enqueue(new Callback<Message>() {
        @Override
        public void onResponse(Call<Message> call, Response<Message> response) {

            Log.d("Response ", "onResponse");
            t1.setText("Notification sent");

        }

        @Override
        public void onFailure(Call<Message> call, Throwable t) {
            Log.d("Response ", "onFailure");
            t1.setText("Notification failure");
        }
    });
}
  

POJOs

 public class Message {
    String to;
    NotifyData notification;

    public Message(String to, NotifyData notification) {
        this.to = to;
        this.notification = notification;
    }

}
  

и

 public class NotifyData {
    String title;
    String body;

    public NotifyData(String title, String body ) {

        this.title = title;
        this.body = body;
    }

}
  

и FirebaseAPI

 public interface FirebaseAPI {

    @POST("/fcm/send")
    Call<Message> sendMessage(@Body Message message);

}
  

Ответ №12:

Здесь рассказывается о том, как получать уведомления без второго сервера, кроме Firebase. Итак, мы используем только Firebase, без дополнительного сервера.

  1. В коде мобильного приложения мы создаем собственную функцию уведомлений с помощью библиотек Android, таких как здесь, без использования библиотек Firebase, как здесь, без Firebase Cloud messaging. Вот пример с Kotlin:

    приватное уведомление о развлечениях () { createNotificationChannel()

      val intent = Intent(this, LoginActivity::class.java).apply {
         flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
     }
     val pendingIntent: PendingIntent = PendingIntent.getActivity(this, 0, intent, 0)
    
     val notificationBuilder = NotificationCompat.Builder(this, "yuh_channel_id")
         .setSmallIcon(R.drawable.ic_send)
         .setContentText("yuh")
         .setContentText("yuh")
         .setAutoCancel(true)
         .setPriority(NotificationCompat.PRIORITY_DEFAULT)
         .setContentIntent(pendingIntent)
     val notificationManager =
         getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
     notificationManager.notify(0, notificationBuilder.build())
    
     with(NotificationManagerCompat.from(this)) {
         // notificationId is a unique int for each notification that you must define
         notify(0, notificationBuilder.build())
     }
      

    }

      private fun createNotificationChannel() {
     // Create the NotificationChannel, but only on API 26  because
     // the NotificationChannel class is new and not in the support library
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
         val name = "yuh_channel"
         val descriptionText = "yuh_description"
         val importance = NotificationManager.IMPORTANCE_DEFAULT
         val CHANNEL_ID = "yuh_channel_id"
         val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
             description = descriptionText
         }
         // Register the channel with the system
         val notificationManager: NotificationManager =
             getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
         notificationManager.createNotificationChannel(channel)
     }
      
  1. В базе данных Firebase создайте коллекцию «ожидающие уведомления». Документы должны содержать имя пользователя (для отправки уведомления) и имя источника (куда пользователь должен перейти, нажав на уведомление).

  2. В коде приложения реализуйте опцию добавления новых записей в коллекцию ожидающих уведомлений. Например. если пользователь A отправляет сообщение пользователю B, то в коллекции создается документ с идентификатором пользователя B (который будет уведомлен).

  3. В коде приложения настройте фоновую службу (когда приложение не видно пользователю). Как здесь. В фоновой службе настройте прослушиватель изменений в коллекции «Ожидающие уведомления». Когда в коллекцию поступит новая запись с идентификатором пользователя, вызовите функцию уведомления, созданную в приведенном параграфе 1, и удалите последующую запись из коллекции.

Ответ №13:

Итак, у меня появилась идея. Смотрите: если FCM, так же как и GCM, имеет конечный результат http-запроса, где мы можем отправить post json с данными нашего сообщения, включая токены устройств, которым мы хотим доставить это сообщение.

Так почему бы не отправить сообщение на сервер Firebase с этим уведомлением, которое будет доставлено пользователю B? вы понимаете?

Итак, вы отправляете сообщение и общаетесь в чате с помощью сообщения о вызове, чтобы гарантировать доставку уведомления, если пользователь работает с вашим приложением в фоновом режиме. Мне это тоже скоро понадобится, я протестирую позже. О чем вы говорите?

Комментарии:

1. У FCM уже есть конечная точка, смотрите здесь . Но это невозможно использовать непосредственно в наших клиентах, поскольку для этого требуется ключ api сервера. И даже если бы это было общедоступно, это вызвало бы проблемы с безопасностью, поскольку любой пользователь смог бы отправить любое сообщение FCM кому угодно.

Ответ №14:

Самый простой способ :

 void sendFCMPush(String msg,String token) {
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    httpClient.addInterceptor(new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request original = chain.request();

            // Request customization: add request headers
            Request.Builder requestBuilder = original.newBuilder()
                    .header("Authorization", "key=" Const.FIREBASE_LEGACY_SERVER_KEY); // <-- this is the important line
            Request request = requestBuilder.build();
            return chain.proceed(request);
        }
    });

    httpClient.addInterceptor(logging);
    OkHttpClient client = httpClient.build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://fcm.googleapis.com/")//url of FCM message server
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())//use for convert JSON file into object
            .build();

    // prepare call in Retrofit 2.0
    FirebaseAPI firebaseAPI = retrofit.create(FirebaseAPI.class);

    //for messaging server
    NotifyData notifydata = new NotifyData("Chatting", msg);

    Call<Message> call2 = firebaseAPI.sendMessage(new Message(token, notifydata));

    call2.enqueue(new Callback<Message>() {
        @Override
        public void onResponse(Call<Message> call, retrofit2.Response<Message> response) {
            Log.e("#@ SUCCES #E$#", response.body().toString());
        }

        @Override
        public void onFailure(Call<Message> call, Throwable t) {

            Log.e("E$ FAILURE E$#", t.getMessage());
        }
    });
}
  

Создайте класс для создания объекта:

 public class Message {
String to;
NotifyData data;

public Message(String to, NotifyData data) {
    this.to = to;
    this.data = data;
}
}
  

Создайте класс для создания объекта:

 public class Notification {
String title;
String message;
enter code here`enter code here`
public Notification(String title, String message) {
    this.title = title;
    this.message = message;
}
}
  

Комментарии:

1. Константа. FIREBASE_LEGACY_SERVER_KEY небезопасно использовать в коде на стороне клиента. Пожалуйста, по крайней мере, прочитайте другие ответы и комментарии перед публикацией.