Après une recherche dans la documentation, je ne trouvais aucune information sur la manière d'envoyer des messages d'un périphérique à l'autre à l'aide de FCM sans utiliser de serveur externe.
Par exemple, si je créais une application de chat, je devrais envoyer des notifications Push aux utilisateurs concernant les messages non lus, car ils ne sont pas toujours en ligne et je ne peux pas avoir de service permanent en arrière-plan auquel je serais toujours connecté. la base de données en temps réel parce que ce serait trop de ressources.
Alors, comment pourrais-je envoyer une notification Push à un utilisateur "A" lorsqu'un certain utilisateur "B" lui envoie un message de discussion? Ai-je besoin d'un serveur externe pour cela ou est-ce possible uniquement avec des serveurs Firebase?
UPDATE: Il est maintenant possible d'utiliser les fonctions cloud de Firebase en tant que serveur pour la gestion des notifications Push. Découvrez leur documentation ici
============
Selon la documentation, vous devez mettre en place un serveur permettant de gérer les notifications Push dans les communications entre périphériques.
Avant de pouvoir écrire des applications clientes utilisant Firebase Cloud Messaging, vous devez disposer d'un serveur d'applications qui répond aux critères suivants:
...
Vous devrez choisir le (s) protocole (s) de serveur de connexion FCM que vous souhaitez utiliser pour permettre à votre serveur d'applications d'interagir avec les serveurs de connexion FCM. Notez que si vous souhaitez utiliser la messagerie en amont à partir de vos applications client, vous devez utiliser XMPP. Pour une discussion plus détaillée à ce sujet, voir Choix d’un protocole de serveur de connexion FCM .
Si vous devez uniquement envoyer des notifications de base à vos utilisateurs à partir du serveur. Vous pouvez utiliser leur solution sans serveur, Notifications Firebase .
Voir une comparaison entre les notifications FCM et Firebase: https://firebase.google.com/support/faq/#messaging-difference
Faire une requête HTTP POST avec le lien https://fcm.googleapis.com/fcm/send avec l'en-tête et les données requis m'a aidé. Dans l'extrait de code ci-dessous, Constants.LEGACY_SERVER_KEY
est une variable de classe locale, que vous pouvez trouver dans votre projet Firebase Settings->Cloud Messaging->Legacy Server key
. Vous devez transmettre le jeton d’enregistrement de périphérique, à savoir regToken
dans l’extrait de code ci-dessous référencé ICI.
Enfin, vous avez besoin de okhttp dépendance à la bibliothèque pour que cet extrait fonctionne.
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();
}
plus loin si vous voulez envoyer un message à un sujet particulier, remplacez regToken
dans json comme ceci
json.put("to","/topics/foo-bar")
et n'oubliez pas d'ajouter l'autorisation INTERNET dans votre fichier AndroidManifest.xml.
IMPORTANT: - L'utilisation du code ci-dessus signifie que la clé de votre serveur réside dans l'application cliente. Cela est dangereux car quelqu'un peut creuser dans votre application et obtenir la clé du serveur pour envoyer des notifications malveillantes à vos utilisateurs.
Vous pouvez le faire en utilisant la requête Volly Jsonobject ....
suivez d'abord ces étapes:
1 copiez la clé de serveur héritée et stockez-la sous le nom Legacy_SERVER_KEY
Clé du serveur hérité
vous pouvez voir sur la photo comment obtenir
2 Vous avez besoin de la dépendance Volley
compile 'com.mcxiaoke.volley: bibliothèque: 1.0.19'
Code pour envoyer 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);
}
Il suffit d'appeler sendFCMPush () ;
Oui, il est possible de le faire sans serveur. Vous pouvez créer un côté client du groupe de périphériques, puis échanger des messages dans le groupe. Cependant, il y a des limites:
Référence: documentation Firebase Consultez la section "Gestion des groupes de périphériques sur Android applications clientes".
1) souscrivez un nom de sujet identique, par exemple:
2) envoyer des messages à l'intérieur de l'application
Les fonctions Google Cloud rendent désormais possible l'envoi de notifications Push d'un appareil à l'autre sans serveur d'applications. J'ai créé une fonction cloud qui se déclenche lorsqu'un nouveau message est ajouté dans la base de données
C'est node.js
code
'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 ;
});
Les fonctions Google Cloud rendent désormais possible l'envoi de notifications Push d'un appareil à l'autre sans serveur d'applications.
De la page correspondante sur Google Cloud Functions:
Les développeurs peuvent utiliser les fonctions de cloud pour que les utilisateurs restent informés des informations pertinentes sur une application. Prenons, par exemple, une application qui permet aux utilisateurs de suivre les activités des autres utilisateurs dans l’application. Dans une telle application, une fonction déclenchée par les écritures de la base de données Realtime pour stocker de nouveaux abonnés pourrait créer des notifications FCM (Firebase Cloud Messaging) afin d'informer les utilisateurs appropriés qu'ils ont gagné de nouveaux abonnés.
Exemple:
La fonction se déclenche lors des écritures sur le chemin de la base de données Realtime où les suiveurs sont stockés.
La fonction compose un message à envoyer via FCM.
FCM envoie le message de notification au périphérique de l'utilisateur.
Voici un projet de démonstration pour l'envoi de notifications Push de périphérique à périphérique avec Firebase et Google Cloud Functions.
Si vous avez un jeton fcm (gcm) du périphérique auquel vous souhaitez envoyer une notification. C'est juste une demande de publication d'envoyer la notification.
Dans mon cas, j'utilise retrofit avec cette classe 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;
}
Les données
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;
}
}
Notification
public class Notification {
private String body;
private String title;
public Notification(String body, String title) {
this.body = body;
this.title = title;
}
}
c'est l'appel
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());
}
});
}
notre serviceAPi
public interface ServiceAPI {
@POST("/fcm/send")
Call<Message> sendMessage(@Header("Authorization") String token, @Body Message message);
}
Vous pouvez utiliser Retrofit. Abonnez-vous aux appareils pour la rubrique actualités Envoyer une notification d'un périphérique à un autre.
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");
}
});
}
POJO
public class Message {
String to;
NotifyData notification;
public Message(String to, NotifyData notification) {
this.to = to;
this.notification = notification;
}
}
et
public class NotifyData {
String title;
String body;
public NotifyData(String title, String body ) {
this.title = title;
this.body = body;
}
}
et FirebaseAPI
public interface FirebaseAPI {
@POST("/fcm/send")
Call<Message> sendMessage(@Body Message message);
}
Alors j'ai eu une idée ici. Voir: Si le FCM, ainsi que le GCM, a une requête endpoit to http où nous pouvons envoyer un message JSON avec nos données de message, y compris le ou les jetons de périphériques que nous voulons que ce message soit remis.
Alors, pourquoi ne pas envoyer un message au serveur Firebase avec cette notification à remettre à l'utilisateur B? tu comprends ?
Ainsi, vous envoyez le message et discutez avec un correspondant pour assurer la livraison de la notification si l'utilisateur est avec votre application en arrière-plan. J'en ai aussi bientôt besoin, je testerai plus tard. De quoi parles-tu?
Pour ce faire, vous pouvez utiliser la base de données temps réel firebase. Vous pouvez créer une structure de données pour stocker les discussions et ajouter des observateurs pour les fils de conversation des deux utilisateurs. Il utilise toujours l'architecture périphérique-serveur-périphérique, mais dans ce cas, il n'y a pas de serveur supplémentaire de la part des développeurs. Cela utilise les serveurs firebase. Vous pouvez consulter un tutoriel ici (ignorer la partie interface utilisateur, bien que ce soit également un bon point de départ pour les frameworks d'interface utilisateur de discussion).