Firebase Cloud Messaging - onMessageReceived не работает

Я хочу создать простую функцию уведомления в своем приложении. Я следил за этим видеороликом YouTube и обоими документами документации Firebase 1 и 2, а также помощником инструмента Firebase в Android Studio (который говорит, что я подключен к Firebase). По некоторым причинам, следуя этим шагам и документам в моем старшем приложении (какой код указан ниже), он не позволит мне получать уведомления. Однако, если я следую тем же шагам в совершенно новом приложении, он отлично работает. Я тестировал оба приложения на одном физическом устройстве и в фоновом режиме, в активных и завершенных состояниях. Каждый раз, когда новое демонстрационное приложение, созданное мной, работает без проблем, но мое старое приложение, которое я хочу получать, не работает. Оба тестируются без получения идентификатора устройства. Я даже не получаю никаких журналов ошибок или журнала TAG. Я думаю, что один из моих скомпилированных проектов мешает, не совсем точно, что, но мне, возможно, придется посмотреть там.

Я также проверил все эти сообщения SO: 1 2 3 и более

PS. Я удалил имя своего пакета ниже, я несколько раз проверял FireBase, и они соответствуют, поэтому я знаю, что это не проблема. Тем не менее, мое новое демо-приложение FireBase показывает, что мое приложение подключено, но мое старое приложение FireBase этого не делало. Кроме того, я поставил щедрость раньше и все еще сталкивался с той же проблемой.

Вот мой проблемный код:

Notification.java (его служба, как и в документации)

public class Notification extends FirebaseMessagingService {
public Notification() {
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    showNotification(remoteMessage.getData().get("message"));

    Log.d("FMC", "Message Notification Body: " + remoteMessage.getNotification().getBody());
}

private void showNotification(String message) {
    Intent i=new Intent(this, SplashScreen.class);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    PendingIntent pendingIntent=PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_UPDATE_CURRENT);
    NotificationCompat.Builder builder=new NotificationCompat.Builder(this)
            .setAutoCancel(true)
            .setContentTitle("FCM TITLE").setContentText(message)
            .setSmallIcon(R.drawable.pt_icon)
            .setDefaults(android.app.Notification.DEFAULT_ALL)
            .setContentIntent(pendingIntent);

    NotificationManager notificationManager= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    notificationManager.notify(0,builder.build());
}
}

Заметьте, что я даже не получил журнал в уведомлении.java выше.

Project.gradle

buildscript {
repositories {
    jcenter()
    maven {
        url 'https://maven.google.com/'
        name 'Google'
    }
}
dependencies {
    classpath 'com.android.tools.build:gradle:3.0.1'
    classpath 'com.google.gms:google-services:3.2.0'

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}
}

allprojects {
repositories {
    jcenter()

    maven { url "https://jitpack.io" }
    maven { url 'https://maven.google.com' }
    google()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

app.gradle

apply plugin: 'com.android.application'

android {
compileSdkVersion 26

defaultConfig {

    minSdkVersion 16
    targetSdkVersion 26
    versionCode 16
    versionName "2.6"
}
dexOptions {
    jumboMode = true
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
//Code below is added to fix random error ("Fix the issues identified by lint")
lintOptions {
    abortOnError false
}
productFlavors {
}
}

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
//compile project(path: ':backend', configuration: 'android-endpoints')
//Removed the 0.2.+
compile 'com.daprlabs.aaron:cardstack:0.3.1-beta0'
//noinspection GradleCompatible
compile 'com.android.support:appcompat-v7:25.4.0'
compile "com.android.support:appcompat-v7:19.0.+"
compile 'com.android.support:design:23.4.0'
compile 'com.android.support:recyclerview-v7:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'

compile 'com.github.danylovolokh:video-player-manager:0.2.0'
compile 'com.github.danylovolokh:list-visibility-utils:0.2.0'



implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.google.firebase:firebase-messaging:11.8.0'
compile 'com.google.firebase:firebase-core:11.8.0'


compile 'com.orhanobut:dialogplus:[email protected]'


compile 'com.nineoldandroids:library:2.4.0'
compile files('libs/sinch-android-rtc-3.9.14.jar')
compile 'com.amazonaws:aws-android-sdk-s3:2.4.4'
compile 'com.github.chrisbanes:PhotoView:1.2.6'
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.5.0'
compile 'com.github.amlcurran.showcaseview:library:5.4.3'
compile 'com.github.d-max:spots-dialog:[email protected]'
compile 'com.victor:lib:1.0.4'
compile 'com.github.bumptech.glide:glide:3.5.2'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.android.support:recyclerview-v7:23.0.0'
compile 'me.grantland:autofittextview:0.2.0'
compile 'com.wang.avi:library:1.0.5'
compile 'com.nineoldandroids:library:2.4.0'
compile 'com.braintreepayments.api:drop-in:2.3.8'
compile 'com.braintreepayments.api:braintree:2.3.9'
compile 'com.loopj.android:android-async-http:1.4.9'
compile 'com.getbase:floatingactionbutton:1.10.1'
compile 'com.mxn.soul:flowingdrawer-core:1.2.2'
compile 'com.github.rengwuxian:MaterialEditText:2.1.4'
compile 'com.github.PhilJay:MPAndroidChart:v3.0.1'
compile 'net.gotev:uploadservice:3.2.5'
compile 'in.srain.cube:ultra-ptr:1.0.11'
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha9'
testCompile 'junit:junit:4.12'
//implementation 'com.android.support:appcompat-v4:23.+'
}


apply plugin: 'com.google.gms.google-services'

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-feature
    android:name="android.hardware.microphone"
    android:required="false" />

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<!--
so the app can be found on tablets Google Play

<uses-permission android:name="android.permission.CALL_PHONE" />
-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!-- <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/> -->
<!-- <uses-permission android:name="android.permission.WAKE_LOCK" /> -->
<!-- <uses-permission android:name="android.permission.READ_PHONE_STATE" /> -->

<grant-uri-permission
    android:path="string"
    android:pathPattern="string"
    android:pathPrefix="string" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/_icon"
    android:label=""
    android:supportsRtl="true"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"
    tools:node="replace">
    <activity android:name=".SplashScreen">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service android:name=".Notification">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <!-- &lt;!&ndash; -->
    <!-- Set custom default icon. This is used when no icon is set for incoming notification messages. -->
    <!-- See README() for more. -->
    <!-- &ndash;&gt; -->
    <!-- <meta-data -->
    <!-- android:name="com.google.firebase.messaging.default_notification_icon" -->
    <!-- android:resource="@drawable/pt_icon" /> -->
    <!-- &lt;!&ndash; -->
    <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming -->
    <!-- notification message. See README() for more. -->
    <!-- &ndash;&gt; -->
    <!-- <meta-data -->
    <!-- android:name="com.google.firebase.messaging.default_notification_color" -->
    <!-- android:resource="@color/colorAccent" /> -->

    <activity android:name=".SignInForm" />
    <activity android:name=".SignUpPage" />
    <activity android:name=".SellerFillOutForm" />
    <activity android:name=".BuyerFillOutForm" />
    <activity
        android:name=".BuyerHomePage"
        android:label="@string/title_activity_buyer_home_page" />

    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="http" />

    <activity android:name=".VideoPlayerActivity" />
    <activity android:name=".BackgroundTask" />

    <service
        android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService"
        android:enabled="true" />

    <activity android:name=".EnterCreditCard" />
    <activity android:name=".PickMeeting" />
    <activity android:name=".HowBillingWorks" />
    <activity android:name=".ReBillingPlan" />
    <activity android:name=".PayBill" />
    <activity
        android:name=".Buyer_Home_Page"
        android:configChanges="locale|orientation" />
    <activity android:name=".Seller_Home_Page" />
    <activity android:name=".ProductList" />
    <activity android:name=".EditProduct" />
    <activity android:name=".EditSellerAccount" />
    <activity android:name=".EditBuyerAccount" />
    <activity android:name=".Video_Calling.incomingVideoCall" />
    <activity android:name=".Video_Calling.CallScreenActivity" />
    <activity android:name=".SellerAnalytics" />
    <activity android:name=".Swipe_Layout.SwipeLayout" />
    <activity android:name=".Swipe_Layout.PopUpActivity" />
</application>

</manifest>

Рабочий код ниже (приложение, которое я сделал для проверки своих шагов и работает на 100%):

Notifaction.java

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import static android.content.ContentValues.TAG;

public class Notifaction extends FirebaseMessagingService {
public Notifaction() {
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    showNotification(remoteMessage.getData().get("message"));
}

private void showNotification(String message) {
    Intent i=new Intent(this,MainActivity.class);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    PendingIntent pendingIntent=PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_UPDATE_CURRENT);
    NotificationCompat.Builder builder=new NotificationCompat.Builder(this)
            .setAutoCancel(true)
            .setContentTitle("FCM TITLE").setContentText(message)
            .setSmallIcon(R.drawable.ic_launcher_background)
            .setDefaults(Notification.DEFAULT_ALL)
            .setContentIntent(pendingIntent);

    NotificationManager notificationManager= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    notificationManager.notify(0,builder.build());
}
}

AndroidManiest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="">
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service
        android:name=".Notifaction">
        <intent-filter>
            <action 
android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>

</application>

</manifest>

app.gradle

apply plugin: 'com.android.application'

android {
compileSdkVersion 26
defaultConfig {
    applicationId ""
    minSdkVersion 14
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.google.firebase:firebase-messaging:11.8.0'
compile 'com.google.firebase:firebase-core:11.8.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}


apply plugin: 'com.google.gms.google-services'

Project.grdle

    // Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

repositories {
    google()
    jcenter()
}
dependencies {
    classpath 'com.android.tools.build:gradle:3.0.1'
    classpath 'com.google.gms:google-services:3.2.0'

    // NOTE: Do not place your application dependencies here; they 
belong
    // in the individual module build.gradle files
}
}

allprojects {
repositories {
    google()
    jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

Кроме того, я добавил файл.json для обоих проектов. Вот скриншот: link.

Ответ 1

Если вы посмотрите на этот документ, у вас нет службы, которая расширяет FirebaseInstanceIdService для управления созданием/поворотом маркера. Вот пример кода. Этот токен, который вам нужно отправить push-уведомления на определенное устройство, получен этим классом.

<service
    android:name=".MyFirebaseInstanceIDService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
    </intent-filter>
</service>

EDIT:

Хорошо, эта ошибка вызывает меня сейчас. Я посмотрел на ваше дерево зависимостей, и вижу, что вы повторяете некоторые из них. Например, у вас есть три версии:

compile 'com.android.support:appcompat-v7:25.4.0'

Возможно, вам следует очистить эту версию до последней версии или сопоставить ее с рабочей версией. Также вы используете новый плагин gradle, но в большинстве случаев вы не обновляли свои зависимости, чтобы использовать implementation вместо compile, возможно, попробовать это? Вот почему вы должны это делать.

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
//compile project(path: ':backend', configuration: 'android-endpoints')
//Removed the 0.2.+
compile 'com.daprlabs.aaron:cardstack:0.3.1-beta0'
//noinspection GradleCompatible
compile 'com.android.support:appcompat-v7:25.4.0'
compile "com.android.support:appcompat-v7:19.0.+"
compile 'com.android.support:design:23.4.0'
compile 'com.android.support:recyclerview-v7:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'

compile 'com.github.danylovolokh:video-player-manager:0.2.0'
compile 'com.github.danylovolokh:list-visibility-utils:0.2.0'



implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.google.firebase:firebase-messaging:11.8.0'
compile 'com.google.firebase:firebase-core:11.8.0'


compile 'com.orhanobut:dialogplus:[email protected]'


compile 'com.nineoldandroids:library:2.4.0'
compile files('libs/sinch-android-rtc-3.9.14.jar')
compile 'com.amazonaws:aws-android-sdk-s3:2.4.4'
compile 'com.github.chrisbanes:PhotoView:1.2.6'
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.5.0'
compile 'com.github.amlcurran.showcaseview:library:5.4.3'
compile 'com.github.d-max:spots-dialog:[email protected]'
compile 'com.victor:lib:1.0.4'
compile 'com.github.bumptech.glide:glide:3.5.2'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.android.support:recyclerview-v7:23.0.0'
compile 'me.grantland:autofittextview:0.2.0'
compile 'com.wang.avi:library:1.0.5'
compile 'com.nineoldandroids:library:2.4.0'
compile 'com.braintreepayments.api:drop-in:2.3.8'
compile 'com.braintreepayments.api:braintree:2.3.9'
compile 'com.loopj.android:android-async-http:1.4.9'
compile 'com.getbase:floatingactionbutton:1.10.1'
compile 'com.mxn.soul:flowingdrawer-core:1.2.2'
compile 'com.github.rengwuxian:MaterialEditText:2.1.4'
compile 'com.github.PhilJay:MPAndroidChart:v3.0.1'
compile 'net.gotev:uploadservice:3.2.5'
compile 'in.srain.cube:ultra-ptr:1.0.11'
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha9'
testCompile 'junit:junit:4.12'
//implementation 'com.android.support:appcompat-v4:23.+'
}

Кроме того, обновите свои зависимости и используйте реализацию вместо компиляции:

implementation 'com.google.firebase:firebase-messaging:15.0.2'
implementation 'com.google.firebase:firebase-core:15.0.2'

Ответ 2

Если вы получаете токен устройства и у вас есть ключ сервера api, проверьте, правильно ли работает ваш код или нет, pushtry. это приведет к ошибке, например, Неверная регистрация, 404 Ошибка и т.д., если вы допустили какую-либо ошибку в своем коде. и для реализации FCM вы можете следовать этому руководству - Учебное пособие по FCM

Еще одна вещь, которую я заметил в вашем файле build.gradle, не существует applicationId "Package Name" в defaultConfig. Я не уверен, но это имя пакета и используется при создании проекта на консоли firebase (название проекта с пакетом)

Ответ 3

Скорее всего, ваши уведомления не отображаются из-за Android Oreo новой модели уведомлений, которая требует указания определений каналов чтобы создавать и показывать уведомления. Также в вашем app.gradle вы настраиваете Android-версию версии 26, которая Android Oreo, поэтому вам придется реализовать код ниже в любом случае.

Легко принять. все, что вам нужно сделать, это:

1. определить канал уведомлений в вашем приложении YourApplicationClass.onCreate()

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            NotificationChannel chan1 = new NotificationChannel(
                YOUR_DESIRED_CHANNEL_ID_STRING,
                YOUR_DESIRED_CHANNEL_LABEL_STRING, 
                NotificationManager.IMPORTANCE_DEFAULT);

            chan1.setDescription(YOUR_DESIRED_CHANNEL_DESC_STRING);//OPTIONAL
            chan1.setLightColor(Color.BLUE);//OPTIONAL     
            chan1.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);//OPTIONAL
            chan1.setShowBadge(true);//OPTIONAL

            getManager().createNotificationChannel(chan1);
        }

2. замените создателя уведомлений на этот конструктор

    NotificationCompat.Builder builder=
new NotificationCompat.Builder(this, YOUR_DESIRED_CHANNEL_ID_STRING);

Полезно знать, что вы можете определить более одного канала с различными свойствами, ориентированными на Android Oreo и выше

Ответ 4

//эта помощь позволяет запустить службу FCM в фоновом режиме при перезагрузке телефона.

Add receiver in Manifest.xml

<uses-permission android:name="android.permission.WAKE_LOCK" />
<receiver android:name=".OnBootBroadcastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
</receiver>

OnBootBroadcastReceiver.class

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class OnBootBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent("com.examle.FirebaseMessagingReceiveService");
        i.setClass(context, FirebaseMessagingReceiveService.class);
        context.startService(i);
    }
}

Ответ 5

Извлеките полезную нагрузку уведомлений из своих сообщений FCM, чтобы получить полезную нагрузку данных по методу onMessageReceived.

Внимательно прочитайте ссылку ниже.

Когда ваше приложение находится в фоновом режиме, полезная нагрузка данных передается методу onMessageReceived только в том случае, если нет полезной нагрузки для уведомлений. (Отметьте слова)

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

Чтобы иметь возможность успешно обслуживать обе платформы, Android и iOS, вам, возможно, придется отправлять различные сообщения FCM в соответствии с клиентской ОС.

Ответ 6

Надеемся, что вы знаете типы уведомлений. Для отправки уведомлений вам нужно использовать настраиваемый сервер или что-то вроде почтальона, для получения дополнительной информации, пожалуйста, ответьте на ответ на этот вопрос:

Как обрабатывать уведомление, когда приложение находится в фоновом режиме в Firebase

В любом случае вам нужно вызвать метод handleIntent (намерение намерения) в вашем FirebaseMessagingService, чтобы вызвать метод onMessageReceived().

Вот мой полный рабочий код, уведомление-когда-приложение-в-фоне-в-firebase.

build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.3'
    defaultConfig {
        applicationId "com.abc.xyz"
        minSdkVersion 17
        targetSdkVersion 26
        multiDexEnabled true
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    dexOptions {
        javaMaxHeapSize "4g"
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:support-v4:26.1.0'
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support:design:26.1.0'
    implementation 'com.android.support:recyclerview-v7:26.1.0'
    implementation 'com.android.support:cardview-v7:26.1.0'
    //firebase analytics and ads
    implementation 'com.google.firebase:firebase-ads:11.4.2'
    implementation 'com.google.firebase:firebase-core:11.4.2'
    implementation 'com.google.firebase:firebase-messaging:11.4.2'
    implementation 'com.firebase:firebase-jobdispatcher:0.8.5'
}

apply plugin: 'com.google.gms.google-services'

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.abc.xyz">

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        <!-- [START fcm_default_icon] -->

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/ic_stat_ic_notification" />

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/colorAccent" />
        <!-- [END fcm_default_icon] -->
        <!-- [START fcm_default_channel] -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="@string/default_notification_channel_id" />
        <!-- [END fcm_default_channel] -->

        <service
            android:name=".services.MyFirebaseMessagingService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
        <service android:name=".services.MyFirebaseInstanceIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>
        <service
            android:name=".services.MyJobService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
            </intent-filter>
        </service>

    </application>

</manifest>

MyFirebaseMessagingService.java:

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "MyFirebaseMsgService";

    @Override
    public void handleIntent(Intent intent) {

        Log.e(TAG, "handleIntent");
        try
        {
            if (intent.getExtras() != null)
            {
                RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

                for (String key : intent.getExtras().keySet())
                {
                    builder.addData(key, intent.getExtras().get(key).toString());
                }

                onMessageReceived(builder.build());
            }
            else
            {
                super.handleIntent(intent);
            }
        }
        catch (Exception e)
        {
            super.handleIntent(intent);
        }
    }

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    // [START receive_message]
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // [START_EXCLUDE]
        // There are two types of messages data messages and notification messages. Data messages are handled
        // here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
        // traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
        // is in the foreground. When the app is in the background an automatically generated notification is displayed.
        // When the user taps on the notification they are returned to the app. Messages containing both notification
        // and data payloads are treated as notification messages. The Firebase console always sends notification
        // messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
        // [END_EXCLUDE]

        // TODO(developer): Handle FCM messages here.
        // Not getting messages here? See why this may be:
        Log.e(TAG, "Notification received Successfully");
        Log.e(TAG, "From: " + remoteMessage.getFrom());

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
            Log.e(TAG, "Message data payload: " + remoteMessage.getData());

            if (/* Check if data needs to be processed by long running job */ true) {
                // For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
                scheduleJob();
            } else {
                // Handle message within 10 seconds
                handleNow();
            }

        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.e(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
        }

        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated. See sendNotification method below.
    }
    // [END receive_message]

    /**
     * Schedule a job using FirebaseJobDispatcher.
     */
    private void scheduleJob() {
        // [START dispatch_job]
        FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this));
        Job myJob = dispatcher.newJobBuilder()
                .setService(MyJobService.class)
                .setTag("my-job-tag")
                .build();
        dispatcher.schedule(myJob);
        // [END dispatch_job]
    }

    /**
     * Handle time allotted to BroadcastReceivers.
     */
    private void handleNow() {
        Log.e(TAG, "Short lived task is done.");
    }

    /**
     * Create and show a simple notification containing the received FCM message.
     *
     * @param messageBody FCM message body received.
     */
    private void sendNotification(String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        String channelId = getString(R.string.default_notification_channel_id);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.ic_stat_ic_notification)
                        .setContentTitle("FCM Message")
                        .setContentText(messageBody)
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
}

MyFirebaseInstanceIDService.java:

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
    private static final String TAG = "MyFirebaseIIDService";

    /**
     * Called if InstanceID token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the InstanceID token
     * is initially generated so this is where you would retrieve the token.
     */
    // [START refresh_token]
    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
        Log.e(TAG, "onTokenRefresh");
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.e(TAG, "Refreshed token: " + refreshedToken);

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // Instance ID token to your app server.
        sendRegistrationToServer(refreshedToken);
    }
    // [END refresh_token]

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user FCM InstanceID token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private void sendRegistrationToServer(String token) {
        // TODO: Implement this method to send token to your app server.
    }
}

MyJobService.java

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class MyJobService extends JobService {

    private static final String TAG = "MyJobService";

    @Override
    public boolean onStartJob(JobParameters job) {
        // Do some work here
        Log.e(TAG, "Inside MyJobService");
        return false; // Answers the question: "Is there still work going on?"
    }

    @Override
    public boolean onStopJob(JobParameters job) {
        Log.e(TAG, "Inside MyJobService");
        return false; // Answers the question: "Should this job be retried?"
    }
}

MyApplication.java:

public class MyApplication extends MultiDexApplication {

    @Override
    public void onCreate() {
        super.onCreate();

        // active JobSchedulerReceiver
        Intent intent = new Intent();
        intent.setAction(getPackageName() + ".receiver.JobSchedulerReceiver");
        sendBroadcast(intent);
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

MainActivity.java:

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.e(TAG, "Inside MainActivity");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Create channel to show notifications.
            String channelId = getString(R.string.default_notification_channel_id);
            String channelName = getString(R.string.default_notification_channel_name);
            NotificationManager notificationManager =
                    getSystemService(NotificationManager.class);
            assert notificationManager != null;
            notificationManager.createNotificationChannel(new NotificationChannel(channelId,
                    channelName, NotificationManager.IMPORTANCE_LOW));
        }

        // If a notification message is tapped, any data accompanying the notification
        // message is available in the intent extras. In this sample the launcher
        // intent is fired when the notification is tapped, so any accompanying data would
        // be handled here. If you want a different intent fired, set the click_action
        // field of the notification message to the desired intent. The launcher intent
        // is used when no click_action is specified.
        //
        // Handle possible data accompanying notification message.
        // [START handle_data_extras]
        if (getIntent().getExtras() != null) {
            for (String key : getIntent().getExtras().keySet()) {
                Object value = getIntent().getExtras().get(key);
                Log.e(TAG, "Key: " + key + " Value: " + value);
            }
        }
        // [END handle_data_extras]

        Button subscribeButton = findViewById(R.id.subscribeButton);
        subscribeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // [START subscribe_topics]
                FirebaseMessaging.getInstance().subscribeToTopic("news");
                // [END subscribe_topics]

                // Log and toast
                String msg = getString(R.string.msg_subscribed);
                Log.e(TAG, msg);
                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
            }
        });

        Button logTokenButton = findViewById(R.id.logTokenButton);
        logTokenButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Get token
                String token = FirebaseInstanceId.getInstance().getToken();

                // Log and toast
                String msg = getString(R.string.msg_token_fmt, token);
                Log.e(TAG, msg);
                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
            }
        });

    }
}

Ответ 7

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

  • Пойдите в свою консоль проекта Firebase, введите параметры проекта и проверьте правильность имени пакета.
  • Загрузите файл JSON еще раз и скопируйте его в модуль app/ (смените проектную перспективу с Android на проект), СОХРАНИТЬ имя файла google-services.json
  • Запустите проект, перейдите к поисковому поиску ключевого слова Firebase, в случае успеха вы увидите сообщение:

I/FirebaseInitProvider: успешная инициализация FirebaseApp

Ответ 8

Даже я столкнулся с одной и той же проблемой, она была решена путем добавления полного пути android: имя службы в AndroidManifest.xml

<service android:name="com.testapp.Notifaction">
     <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

попробуйте один раз и сообщите мне, есть ли у вас какие-либо проблемы.

Ответ 9

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

  • Ваши зависимости от gradle выглядят отлично, но вам просто нужна implementation "com.google.firebase:firebase-messaging:15.0.2"

  • Не могли бы вы переименовать свой класс в нечто другое? Имя Notification может быть связано с собственным классом Android Notification. Также помните, что он должен иметь пустой конструктор (но я вижу в вашем коде, что у вас есть)

Назовите его MessagingController, например, и поместите его в свой манифест внутри <application> например:

   <!--Service to control messaging requests-->
        <service
            android:name=".messaging.controller.MessagingController"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
    </application>

Кроме того, не забывайте, что вам нужен экземпляр FirebaseInstanceService, это требуется, как в Официальном Доке:

Служба, которая расширяет FirebaseInstanceIdService для обработки создания, вращения и обновления регистрационных токенов. Это необходимо для отправки на определенные устройства или для создания групп устройств.

<!--Firebase instance service to renew messaging tokens-->
        <service
            android:name=".messaging.service.FirebaseInstanceService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>
  • Вы отправляете уведомления из Firebase Console? Или использовать функции Cloud Firebase? В обоих случаях вы вводите правильный токен? Если вы установили тайм-аут, то консоль Firebase покажет вам ошибку, вы должны добавить уведомление следующим образом:

enter image description here

  • Хорошо, на данный момент, с вашим кодом, это должно быть, по крайней мере, получение уведомлений в ваших журналах,

  • Если вы хотите, вы можете проверить следующий проект, который является приложением Skeleton для создания системы уведомлений. Возможно, это тоже поможет: https://github.com/FrangSierra/PushNotificationSkeleton

  • Наконец, если вы хотите проверить код облачной функции о том, как отправлять уведомления с сервера, я предлагаю вам посмотреть на этот репозиторий

Ответ 10

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

Ответ 11

Вы зарегистрировали свое приложение на консоли FCM? И добавил файл .json в ваше приложение?

Ответ 12

существует два типа данных уведомления 1) полезная нагрузка уведомления 2) полезная нагрузка данных если вы отправляете данные с сервера в средстве оповещения уведомлений. есть шанс, что вы не вызвали onMessageRecieved() из FirbaseMessagingService, посмотрите эту ссылку

Ответ 13

Это просто простое предложение, но то, что вызвало аналогичную ошибку для меня пару недель назад, состояло в том, что я отправил неправильную форму уведомления. Я отправил тихие уведомления, хотя я должен был послать громко. Проверьте, как ваш сервер отправляет сообщения. Я также испортил порядок, в котором API FCM ожидает ключи.

Вот мой код для рабочих громких уведомлений, которые отправляются сервером Django Python:

def _build_loud_message(not_id, data):
    """Construct loud notifiation message.
    Loud means that this message will show up in the notifications hub
    of the app.
    """
    return {
        'message': {
            'notification': {
                'title': 'New activity',
                'body': 'Hey you have some new activity!'
            },
            'data': {"data": data},
            'apns': {
                'payload': {
                    "notId": not_id,  # notId HAS TO BE FIRST!!!
                    'aps': {
                        'badge': 1,
                        'sound': 'default',
                        'content-available': 1
                    }
                },
                'headers': {
                    'apns-priority': '10',
                    'apns-collapse-id': 'myid-1'
                }
            },
            'android': {
                'priority': "high",
                'data': {
                    "androidData": data
                },
                'notification': {
                    'sound': 'default',
                    'tag': 'mytag-1'
                }
            }
        }
    }

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