fcm - firebase send notification java
Notificación de Firebase Cloud Messaging desde Java en lugar de Firebase Console (8)
Soy nuevo en Firebase y me estoy encontrando con errores como Id de remitente no coincidente y Error de autenticación con estado HTTP 401 cuando mi aplicación Java intenta enviar una notificación / mensaje usando el token de Firebase del cliente. Tenga en cuenta que al utilizar Firebase Console, puedo enviar el mensaje al cliente.
Para la aplicación cliente, hice lo siguiente:
- Cloned la aplicación de inicio rápido de
messaging
Firebase desde aquí - https://github.com/firebase/quickstart-android/tree/master/messaging - que ya está configurada con dependencias de Firebase y tal. Cargó la aplicación clonada enAndroid Studio
. - Al usar Firebase Console, creé un nuevo proyecto llamado
My Notification Client
y agregué una aplicación usandocom.google.firebase.quickstart.fcm
como el nombre del paquete de la aplicación de Android. - Se
google-services.json
archivogoogle-services.json
para la aplicación de Android agregado al proyecto recién creado y se copió en la carpeta demessaging/app/
y se sincronizó con archivos de Grade desdeAndroid Studio
. - Creó un emulador y ejecutó la aplicación desde
Android Studio
. Cuando la aplicación se cargó en el emulador, hizo clic en el botónLog Token
para capturar el token de Firebase del cliente en la pestañaAndroid Monitor
enAndroid Studio
. - Al usar Firebase Console, seleccioné el proyecto recién creado
My Notification Client
, hice clic en el enlaceNotifications
en el panel izquierdo y envié una notificación al dispositivo al pegar el token de Firebase capturado en el paso anterior.
Esto funcionó muy bien! El siguiente paso fue utilizar una aplicación Java simple separada (que eventualmente se convertiría en un servidor de notificaciones) para enviar la notificación al cliente en lugar de utilizar Firebase Console.
Para lograr esto, seguí los pasos descritos aquí: https://firebase.google.com/docs/server/setup#prerequisites . Específicamente, estos son los pasos que realicé:
- Creó un nuevo proyecto llamado
My Notification Server
en Firebase Console. - Utilizando
Settings > Permissions
en Firebase Console, creó una nueva cuenta de servicio y descargó el archivoserviceAccountCredentials.json
. - Creó un nuevo proyecto maven en Eclipse y agregó las siguientes dependencias en pom.xml:
<dependency>
<groupId>com.google.gcm</groupId>
<artifactId>gcm-server</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.google.firebase</groupId>
<artifactId>firebase-server-sdk</artifactId>
<version>3.0.0</version>
</dependency>
Luego,
FCMSender
com.google.android.gcm.sender.Sender
para crearFCMSender
yFCMSender
método protegidogetConnection(String url)
para usar el nuevo punto final de FCM como se muestra a continuación:class FCMSender extends Sender { public FCMSender(String key) { super(key); } @Override protected HttpURLConnection getConnection(String url) throws IOException { String fcmUrl = "https://fcm.googleapis.com/fcm/send"; return (HttpURLConnection) new URL(fcmUrl).openConnection(); } }
El método
main()
de mi aplicación Java se ve así:public static void main(String[] args) { // Obtain serverKey from Project Settings -> Cloud Messaging tab // for "My Notification Client" project in Firebase Console. String serverKey = <get_server_key_from_firebase_console>; Thread t = new Thread() { public void run(){ try { Sender sender = new FCMSender(serverKey); Message message = new Message.Builder() .collapseKey("message") .timeToLive(3) .delayWhileIdle(true) .addData("message", "Notification from Java application"); .build(); // Use the same token(or registration id) that was earlier // used to send the message to the client directly from // Firebase Console''s Notification tab. Result result = sender.send(message, "APA91bFfIFjSCcSiJ111rbmkpnMkZY-Ej4RCpdBZFZN_mYgfHwFlx-M1UXS5FqDBcN8x1efrS2md8L9K_E9N21qB-PIHUqQwmF4p7Y3U-86nCGH7KNkZNjjz_P_qjcTR0TOrwXMh33vp", 1); System.out.println("Result: " + result.toString()); } catch (Exception e) { e.printStackTrace(); } }; t.start; try { t.join(); } catch (InterruptedException iex) { iex.printStackTrace(); } }
Cuando ejecuto la aplicación Java, MismatchSenderId
error MismatchSenderId
. Intenté solucionar problemas usando curl
como se muestra a continuación pero obtuve el mismo error:
$ skey=<obtained_from_project_settings_cloud_messaging_tab_in_firebase_console>
$ curl -X POST --header "Authorization: key=$skey" /
--Header "Content-Type: application/json" /
https://fcm.googleapis.com/fcm/send /
-d "{/"to/":/"APA91bFfIFjSCcSiJ111rbmkpnMkZY-Ej4RCpdBZFZN_mYgfHwFlx-M1UXS5FqDBcN8x1efrS2md8L9K_E9N21qB-PIHUqQwmF4p7Y3U-86nCGH7KNkZNjjz_P_qjcTR0TOrwXMh33vp/",/"data/":{/"message/":/"Yellow/"}}"
{"multicast_id":7391851081942579857,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}
En lugar de usar la Server Key
del Server Key
figura en Project Settings > Cloud Messaging
pestaña Project Settings > Cloud Messaging
para el proyecto My Notification Server
en Firebase Console, traté de usar el Project Number
del Project Number
pero causó InvalidRequestException: HTTP Status Code: 401
.
La documentación de Firebase de los códigos de error dice esto sobre MismatchSenderId
:
No coincidente Sender 200 +
error:MismatchSenderId
Un token de registro está vinculado a un determinado grupo de remitentes. Cuando una aplicación cliente se registra para FCM, debe especificar qué remitentes pueden enviar mensajes. Debe usar una de esas ID de remitente al enviar mensajes a la aplicación cliente. Si cambia a un remitente diferente, los tokens de registro existentes no funcionarán.
No pude averiguar dónde / cómo en Firebase Console se puede configurar la aplicación de Android (que se agregó al proyecto My Notification Client
) para poder recibir mensajes.
¡Cualquier ayuda en esto sería apreciada!
Utiliza este envío de notificaciones push desde java.
Marco de primavera
En comparación con otros proyectos, solo hay 3 clases simples con dependencias mínimas.
https://github.com/AndreiD/testingpushnotifications
Recuerde reemplazar el SERVER_API_KEY y el Client_Token.
Acabo de comenzar con FireBase, pero parece que alguien (Brandon Gresham) ya ha creado una API Java de firebase.
Puede consultar las API de terceros para diferentes idiomas aquí: https://firebase.google.com/docs/database/rest/start
Y aquí está el de Java: https://github.com/bane73/firebase4j
¡Muchas gracias a Brandon por dedicarle tiempo!
En:
// Obtain serverKey from Project Settings -> Cloud Messaging tab // for "My Notification Server" project in Firebase Console. String serverKey = <get_server_key_from_firebase_console>;
Debes obtener la clave para tu aplicación de Android.
Y gracias, estaba luchando por crear un servicio para enviar / recibir notificaciones de la aplicación. Vi tu pregunta, traté de hacerlo bien y solía construir la mía. Espero que esto te ayudará :)
Escribí una Clase FCMHelper, que funciona bien y es fácil de usar.
Mira aquí https://github.com/MOSDEV82/fcmhelper
Me encontré con el mismo problema. El problema estaba en la línea:
String serverKey = <get_server_key_from_firebase_console>;
Este valor debe venir del proyecto de la aplicación Android; en este caso, sería "My Notification Client" y no "My Notification Server".
Necesitaba enviar notificaciones FCM desde mi aplicación java EE y encontré this muy útil. Podría salvar a alguien en algún momento.
... El repositorio github es una interfaz de biblioteca para la API de Firebase Cloud Messaging (FCM) (NB // No soy el autor). Así que seguí las instrucciones en el archivo léame: agregué el archivo jar como una dependencia de mi proyecto y pude invocar los métodos de la biblioteca con los parámetros respectivos.
por ejemplo, Pushraven.setKey(my_key);
para configurar su clave de servidor y
Notification raven = new Notification();
raven.title("MyTitle")
.text("Hello World!")
.color("#ff0000")
.to(client_key);
para construir una notificación Las instrucciones del repositorio son bastante claras y útiles.
También recientemente comencé a usar Firebase, sin experiencia previa en Google Cloud Messaging. AFAIK, actualmente no hay un SDK del lado del servidor para Firebase Cloud Messaging.
Para enviar notificaciones / mensajes desde su servidor de aplicaciones a su cliente móvil, debe implementar sus propios métodos HTTP y / o XMPP. Ver https://firebase.google.com/docs/cloud-messaging/
Mi código de prueba, usando HTTP:
public CompletableFuture<String> fcmTest1() {
// https://firebase.google.com/docs/cloud-messaging/http-server-ref
String host = "fcm.googleapis.com";
String requestURI = "/fcm/send";
String CLIENT_TOKEN = "ASK_YOUR_MOBILE_CLIENT_DEV"; // https://developers.google.com/instance-id/
CompletableFuture<String> fut = new CompletableFuture<>();
JsonObject body = new JsonObject();
// JsonArray registration_ids = new JsonArray();
// body.put("registration_ids", registration_ids);
body.put("to", CLIENT_TOKEN);
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);
HttpClientRequest hcr = httpsClient.post(443, host, requestURI).handler(response -> {
response.bodyHandler(buffer -> {
logger.debug("FcmTest1 rcvd: {}, {}", response.statusCode(), buffer.toString());
if (response.statusCode() == 200) {
fut.complete(buffer.toString());
} else {
fut.completeExceptionally(new RuntimeException(buffer.toString()));
}
});
});
hcr.putHeader("Authorization", "key=" + Utils.FIREBASE_SERVER_KEY)
.putHeader("content-type", "application/json").end(body.encode());
return fut;
}
Nota: el cliente http y json fueron proporcionados por vertx ( http://vertx.io/ ), pero es de esperar que el código muestre lo que está sucediendo lo suficientemente claro para que pueda usar lo que desee.
Tuve exactamente el mismo problema, e incluso utilicé su código como prueba para verificar si había algún problema con el mío. Resulta que nuestros dos códigos eran correctos. El problema es exactamente como se describe en los documentos de Firebase:
"Error del remitente no coincidente 200 +: MismatchSenderId Un token de registro está vinculado a un determinado grupo de remitentes. Cuando una aplicación cliente se registra para FCM, debe especificar qué remitentes pueden enviar mensajes. Debe usar uno de esos identificadores de remitente al enviar mensajes. a la aplicación del cliente. Si cambia a un remitente diferente, los tokens de registro existentes no funcionarán ".
El problema es que eso no está claro (al menos no fue para mí). Así que esto es lo que necesita: en su aplicación de Android, deberá recibir la clave de Firebase para el dispositivo. Ya no es lo mismo que solía tener para Google Cloud Message, y ahí está el problema.
Simplemente crea esta clase en tu proyecto de Android:
la clase pública NotificacaoRegistro extiende FirebaseInstanceIdService {static private String TAG = "NOTIFICACAOREGISTRO";
public NotificacaoRegistro(){
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
}
@Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// TODO: Implement this method to send any registration to your app''s servers.
}
}
No olvides hacer los cambios necesarios en tu AndroidManifest
<service
android:name=".notificacoes.NotificacaoRegistro">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
Si solo necesita el código (para la depuración, por ejemplo) puede simplemente invocar su MainActivity, en su método OnCreate
String refreshedToken = FirebaseInstanceId.getInstance (). GetToken ();
Pero es mejor, por supuesto, si te ocupas de eso correctamente.
De esa forma obtendrás la clave correcta para ese dispositivo. Luego, en tu código de aplicación Java
Result result = sender.send(message,
<PUT THE VALUE OF THE REFRESHED TOKEN HERE>,
1);
y estás todo listo :)
Espero que esto ayude, y perdón por la larga demora :)
aclamaciones