Я вызываю sendToToken ("токен") с действительным токеном моего устройства, и он не работает, я не понимаю, чего мне не хватает, не выходит из строя, я отлаживаю, отправляю его правильно, но уведомление просто не появляется на целевом устройстве, на котором установлено мое приложение .
Что мне не хватает, может ли кто-нибудь помочь мне разобраться? Я и мой партнер боролись с этим в течение нескольких недель
MyFirebaseMessagingService.java
package com.example.intercambiolibros.fragments;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import org.json.JSONException;
import org.json.JSONObject;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage message) {
super.onMessageReceived(message);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "channel_id")
.setContentTitle(message.getNotification().getTitle())
.setContentText(message.getNotification().getBody())
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setStyle(new NotificationCompat.BigTextStyle())
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setAutoCancel(true);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
класс, куда я отправляю уведомления:
package com.example.intercambiolibros.fragments;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.intercambiolibros.R;
import com.example.intercambiolibros.activitys.LoginActivity;
import com.example.intercambiolibros.models.Libros;
import com.example.intercambiolibros.support.Constantes;
import com.example.intercambiolibros.support.conversaciones.Conversacion;
import com.example.intercambiolibros.support.mensajes.MensajeEnviar;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ServerValue;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.*;
import org.ocpsoft.prettytime.PrettyTime;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
public class LibrosInicioShow extends Fragment {
private RecyclerView recyclerView;
private BookAdapter bookAdapter;
private EditText searchEditText;
private List<Libros> bookList;
private List<Libros> allBooks;
public String getMode() {
return mode;
}
public void setMode(String mode) {
this.mode = mode;
}
private String mode = "";
private DatabaseReference databaseReference;
private void setFCMToken() {
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference usersRef = database.getReference("users");
String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
// Get the device token for the current user
FirebaseMessaging.getInstance().getToken()
.addOnCompleteListener(new OnCompleteListener<String>() {
@Override
public void onComplete(@NonNull Task<String> task) {
if (!task.isSuccessful()) {
Log.w("FCM", "Fetching FCM registration token failed", task.getException());
}
// Get the device token from the task result
String token = task.getResult();
// Save the device token to the database for the current user
usersRef.child(userId).child("deviceToken").setValue(token);
}
});
}
private RemoteMessage getMessage() {
final HashMap<String, String> map = new HashMap<>();
map.put("message", "From DesertSync");
map.put("xfrom", "Prueba");
return new RemoteMessage.Builder("internal").setData(map).build();
}
public void sendToToken(String token) {
// [START send_to_token]
// This registration token comes from the client FCM SDKs.
FirebaseMessaging.getInstance().send(
new RemoteMessage.Builder(token + "@gcm.googleapis.com")
.setMessageId("" + System.currentTimeMillis())
.addData("msg", "ping")
.addData("ts", "" + System.currentTimeMillis())
.build());
// Response is a message ID string.
// [END send_to_token]
}
Модуль Build.gradle: приложение
plugins {
id 'com.android.application'
id 'com.google.gms.google-services'
}
android {
namespace 'com.example.intercambiolibros'
compileSdk 32
defaultConfig {
applicationId "com.example.intercambiolibros"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation platform('com.google.firebase:firebase-bom:31.1.0')
implementation 'com.google.firebase:firebase-messaging:23.1.2'
implementation 'com.google.firebase:firebase-messaging'
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-analytics'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
// implementation 'com.android.support:support-annotations:28.0.0' mala
implementation 'com.google.firebase:firebase-auth:21.1.0'
implementation 'com.google.firebase:firebase-database:20.1.0'
//
implementation 'com.google.firebase:firebase-analytics:21.2.0'
implementation 'com.google.firebase:firebase-common-ktx:20.2.0'
// //implementation 'com.google.firebase:firebase-common-ktx:20.2.0'
//
implementation 'com.firebaseui:firebase-ui-database:8.0.2'
implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation "com.github.bumptech.glide:glide:4.13.0"
implementation 'com.google.firebase:firebase-storage:20.1.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.google.firebase:firebase-messaging:23.1.0'
implementation 'org.ocpsoft.prettytime:prettytime:5.0.4.Final'
implementation 'com.google.firebase:firebase-firestore:24.5.0'
implementation 'com.google.android.gms:play-services-nearby:18.0.2'
}
проект build.gradle
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.3.14'
repositories {
google()
mavenCentral()
dependencies {
// Add the dependency for the Google services Gradle plugin
classpath 'com.google.gms:google-services:4.3.14'
}
}
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.4.0' apply false
id 'com.android.library' version '7.4.0' apply false
}
AndroidManifest.xml
<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:tools = "http://schemas.android.com/tools">
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name = "android.permission.POST_NOTIFICATIONS"/>
<application
android:usesCleartextTraffic = "true"
android:name = ".support.ColorDinamico"
android:allowBackup = "true"
android:dataExtractionRules = "@xml/data_extraction_rules"
android:fullBackupContent = "@xml/backup_rules"
android:icon = "@mipmap/ic_launcher"
android:label = "@string/app_name"
android:roundIcon = "@mipmap/ic_launcher"
android:supportsRtl = "true"
android:theme = "@style/Theme.IntercambioLibros"
tools:targetApi = "33">
<activity android:name = ".activitys.DashBoardActivity" />
<activity android:name = ".activitys.LoginActivity" />
<activity android:name = ".activitys.registro_activity" />
<activity
android:name = ".activitys.SplashActivity"
android:exported = "true">
<intent-filter>
<action android:name = "android.intent.action.MAIN" />
<category android:name = "android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name = ".support.MyFirebaseMessagingService2"
android:exported = "true">
<intent-filter>
<action android:name = "com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
Вкратце: нет возможности отправить сообщение через FCM напрямую с одного устройства на другое. Вам нужно будет вызвать FCM из доверенной среды, чтобы отправить сообщение на устройство.
Метод send, который вы вызываете, задокументирован как:
Отправляет
messageвверх по течению на ваш сервер приложений.
Вы захотите взглянуть на эту диаграмму из обзора архитектуры , чтобы понять, что это означает:
Когда вы звоните send, клиент отправляет сообщение в FCM, который доставляет его на настроенный вами сервер приложений. Он не доставляет сообщение на другое устройство.
Чтобы отправить сообщение на устройство, вам нужно прочитать документацию по созданию запросов на отправку на вашем сервере приложений. Там есть примеры как с использованием Firebase Admin SDK для различных платформ, так и с вызовами REST API. Самое важное, что нужно понимать, это то, что такие вызовы всегда должны исходить из доверенной среды/сервера приложений, такого как ваш компьютер для разработки, сервер, которым вы управляете, или что-то вроде Cloud Functions/Cloud Run.
API для создания кампаний отсутствует, поэтому сообщения, отправленные через API, действительно не будут отображаться в консоли Firebase. --- Чтобы устранить неполадки с доставкой сообщений, см. firebase.google.com/docs/cloud-messaging/understand-delivery
Спасибо за документы, действительно полезный ответ, я отправляю его, следуя всем примерам, приложение сообщает мне, что сообщение успешно отправлено, но оно не отображается в моей консоли сообщений firebase как новая кампания, а также на устройстве, которое я отправляю. Нужно ли мне давать какое-либо разрешение конкретному устройству, чтобы увидеть push-уведомление?