アプリがバックグラウンドにあるときにFirebase onMessageReceivedが呼び出されない


233

Firebaseを使用して、アプリがバックグラウンドにあるときにサーバーからアプリへの通知の送信をテストしています。通知は正常に送信され、デバイスの通知センターにも表示されますが、通知が表示されたとき、またはクリックした場合でも、FCMEsagingService内のonMessageReceivedメソッドが呼び出されることはありません。

アプリがフォアグラウンドにあるときにこれをテストすると、onMessageReceivedメソッドが呼び出され、すべてが正常に機能しました。この問題は、アプリがバックグラウンドで実行されているときに発生します。

これは意図された動作ですか、またはこれを修正する方法はありますか?

これが私のFBMessagingServiceです。

import android.util.Log;

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

public class FBMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.i("PVL", "MESSAGE RECEIVED!!");
        if (remoteMessage.getNotification().getBody() != null) {
            Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getNotification().getBody());
        } else {
            Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getData().get("message"));
        }
    }
}

json本体に加えて、onTokenRefreshコードはどこにありますか?Androidのセットアップを完了しましたか?
加藤

4
通知のjson本文とはどういう意味ですか?また、私のonTokenRefreshコードはFirebaseInstanceIDサービス内にあります。
Cyogenos

送信するサンプルペイロードを投稿できますか?
AL。


また、このスレッドをチェックすることができますstackoverflow.com/questions/39046270/...
メリーランドSajedulカリム。

回答:


144

これは意図したとおりに機能しており、アプリがフォアグラウンドにある場合にのみ、通知メッセージがonMessageReceivedコールバックに配信されます。アプリがバックグラウンドまたは閉じている場合、通知メッセージが通知センターに表示され、そのメッセージのデータは、ユーザーが通知をタップした結果として起動されたインテントに渡されます

click_actionを指定して、ユーザーが通知をタップしたときに起動するインテントを指定できます。メインアクティビティは、click_actionが指定されていない場合に使用されます。

インテントが起動されると、

getIntent().getExtras();

通知メッセージとともに送信されたデータを含むセットを取得します。

通知メッセージの詳細については、ドキュメントを参照してください。


6
click_actionFirebase Notification Consoleを使用しているときにを設定する方法はありますか?
Nii Laryea 2016年

6
わかりましたが、アプリが強制終了された場合(フォアグラウンドまたはバックグラウンドなし)はどうなりますか?
michalu 2016年

3
しかし、ユーザー破棄通知を無効にする方法は?ユーザーがそれを破棄すると、それはすべてのデータがスキップされることを意味するからです...
Aleksey Timoshchenko 2016

4
正しい!したがって、Androidに通知メッセージを送信する場合、付随するデータは、通知エクスペリエンスを向上させるデータである必要があります。アプリの重要なデータではなく、ユーザーが通知を却下した場合でも、アプリケーションが必要とするデータにはデータメッセージを使用してください。
Arthur Thompson

3
これは完全に正しいわけではありません。メッセージにデータのみが含まれ、通知ペイロードが含まれていない場合、アプリがフォアグラウンドにあるかどうかにかかわらず、メッセージは常にonMessageReceiveに配信されます。
JacksOnF1re 2017

125

notificationサーバーリクエストからフィールドを完全に削除します。送信のみdataで処理しonMessageReceived()ます。それ以外の場合onMessageReceived()は、アプリがバックグラウンドで実行されているか強制終了されてもトリガーされません。

"priority": "high"通知リクエストにフィールドを含めることを忘れないでください。ドキュメントによると:データメッセージは通常の優先順位で送信されるため、すぐには届きません。それも問題である可能性があります。

これは私がサーバーから送信しているものです

{
  "data":{
    "id": 1,
    "missedRequests": 5
    "addAnyDataHere": 123
  },
  "to": "fhiT7evmZk8:APA91bFJq7Tkly4BtLRXdYvqHno2vHCRkzpJT8QZy0TlIGs......",
  "priority": "high"
}

だからあなたはonMessageReceived(RemoteMessage message)このようにあなたのデータを受け取ることができます... IDを取得する必要があるとしましょう

Object obj = message.getData().get("id");
        if (obj != null) {
            int id = Integer.valueOf(obj.toString());
        }

9
データメッセージのみを送信すると、タスクマネージャーからクリアされたアプリは通知を取得できなくなります。これは意図された動作ですか?
Prabhjot Singh

2
これは私がバックグラウンドでメッセージを受信するための解決策でした!
Ray Hulha 2017年

5
Oreoでアプリを強制終了すると、onMessageReceivedが呼び出されません。データだけのペイロードがあります。何かアップデートはありますか?
Samir Mangroliya、2018

2
魅力的な作品!
2018年

3
この回答をたくさん愛してください:p
Ahmad Arslan

63

このメソッドhandleIntent()は廃止されたため、通知の処理は次のように実行できます。

  1. フォアグラウンド状態:通知のクリックは、通知のデータペイロードで一般的に作成されるように、プログラムで通知を作成するときに提供する保留中のインテントのアクティビティに移動します。

  2. バックグラウンド/強制終了状態-ここでは、システム自体が通知ペイロードに基づいて通知を作成し、その通知をクリックすると、アプリケーションのランチャーアクティビティに移動し、任意のライフサイクルメソッドでインテントデータを簡単にフェッチできます。


ありがとうございました!!!私はこの問題で数日を失い、これは私を救いました。
イゴールヤンコビッチ2017年

本当に完璧なソリューションです!
EduXavier 2017年

4
私はhandleIntent(Intent intent)で通知表示ロジックを処理していますが、アプリがバックグラウンドにある場合、2つの通知が表示されます。1つは私が作成した通知で、もう1つはデフォルトで通知からのメッセージ全体を含みます。
ジョイソン2017年

5
素晴らしいですがOnMessageReceived、この場合は何の用途もありません!?
Alaa AbuZarifa 2017年

8
firebaseメッセージング:私はcom.google.firebaseを抱えている11.6.2&handleIntentが最終now.Checkのあるstackoverflow.com/questions/47308155/...
Ronak Poriya

31

次に、firebaseメッセージに関するより明確な概念を示します。彼らのサポートチームから見つけました。

Firebaseには3つのメッセージタイプがあります

通知メッセージ:通知メッセージは、バックグラウンドまたはフォアグラウンドで機能します。アプリがバックグラウンドにある場合、通知メッセージはシステムトレイに配信されます。アプリがフォアグラウンドにある場合、メッセージはonMessageReceived()またはdidReceiveRemoteNotificationコールバックによって処理されます。これらは基本的にディスプレイメッセージと呼ばれるものです。

データメッセージ:Androidプラットフォームでは、データメッセージはバックグラウンドとフォアグラウンドで機能します。データメッセージは、onMessageReceived()によって処理されます。ここでのプラットフォーム固有の注意事項は次のとおりです。Androidでは、データペイロードは、アクティビティの起動に使用されるインテントで取得できます。詳しく説明すると、があれば"click_action":"launch_Activity_1"getIntent()からのみこのインテントを取得できますActivity_1

通知ペイロードとデータペイロードの両方を含むメッセージ:バックグラウンドでは、アプリは通知トレイで通知ペイロードを受信し、ユーザーが通知をタップしたときにのみデータペイロードを処理します。フォアグラウンドでは、アプリは両方のペイロードが利用可能なメッセージオブジェクトを受け取ります。次に、click_actionパラメータは、データペイロードではなく通知ペイロードでよく使用されます。データペイロード内で使用する場合、このパラメーターはカスタムのKey-Valueペアとして扱われるため、意図したとおりに機能させるにはカスタムロジックを実装する必要があります。

また、onMessageReceivedメソッド(データメッセージを参照)を使用してデータバンドルを抽出することをお勧めします。あなたのロジックから、私はバンドルオブジェクトをチェックしましたが、予期されたデータコンテンツが見つかりませんでした。これは、より明確にするために類似のケースへの参照です。

サーバー側から、firebase通知は次の形式である必要があります

サーバー側は「通知」オブジェクトを送信する必要があります。の「通知」オブジェクトの欠如は、TargetActivityを使用してメッセージを受信しませんでしたgetIntent()

正しいメッセージ形式を以下に示します。

{
 "data": {
  "body": "here is body",
  "title": "Title"
 },
"notification": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
 "to": "ffEseX6vwcM:APA91bF8m7wOF MY FCM ID 07j1aPUb"
}

次に、firebaseメッセージに関するより明確な概念を示します。彼らのサポートチームから見つけました。

詳細については、私のこのスレッドこのスレッドにアクセスしてください


3
デバイスがディープドーズモード(Android 7.0で導入)の場合、「データメッセージ」は受信されないことに言及する価値があります。それらに注意してください!
Sameer J

30

同じ問題がありました。「通知」の代わりに「データメッセージ」を使用する方が簡単です。データメッセージは常にクラスonMessageReceivedをロードします。

そのクラスでは、notificationbuilderを使用して独自の通知を行うことができます。

例:

 @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        sendNotification(remoteMessage.getData().get("title"),remoteMessage.getData().get("body"));
    }

    private void sendNotification(String messageTitle,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_UPDATE_CURRENT);

        long[] pattern = {500,500,500,500,500};

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setVibrate(pattern)
                .setLights(Color.BLUE,1,1)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

7
ありがとうございます。サーバーコードを変更し、「通知」の代わりに「データ」を使用しました。これで完全に機能します
Mahesh Kavathiya

5
アプリがフォアグラウンドにある場合にのみ機能し、バックグラウンドにある場合は機能しません。どちらの場合でも、このイベントをトリガーするのに役立ちますか?
Anant Shah

@AnantShah FirebaseサーバーへのPOSTはどのように見えますか?
Koot 2016

3
ここでは実際には3つのケースが考えられます。1)フォアグラウンドのアプリ。2)バックグラウンドでのアプリ。3)アプリが実行されていません。あなたが言うように、アプリが実行されていない場合、最初の2つのケースでは「データ」メッセージが受信されますが、3番目のケースでは受信されません。3つのケースすべてに対応するには、メッセージの「通知」フィールドを設定する必要があります。(iOSおよびAndroidクライアントをサポートする場合も良い考えです)
Steve Moseley

1
アプリが実行されていなくても、onmessagereceived関数でサーバーからメッセージを取得します。iOSもサポートしたい場合は、「通知」を使用する方がよいことに同意します。
Koot

21

Firebase Cloud Messagingのドキュメントに従って、アクティビティがフォアグラウンドにある場合、onMessageReceivedが呼び出されます。アクティビティがバックグラウンドにあるか閉じている場合、アプリランチャーのアクティビティに関する通知メッセージが通知センターに表示されます。次のように、FirebaseメッセージングのRESTサービスAPIを呼び出すことにより、アプリがバックグラウンドである場合に、通知をクリックするだけでカスタマイズされたアクティビティを呼び出すことができます。

URL- https://fcm.googleapis.com/fcm/send

メソッドタイプ-POST

Header- Content-Type:application/json
Authorization:key=your api key

本体/ペイロード:

{ "notification": {
    "title": "Your Title",
    "text": "Your Text",
     "click_action": "OPEN_ACTIVITY_1" // should match to your intent filter
  },
    "data": {
    "keyname": "any value " //you can get this data as extras in your activity and this data is optional
    },
  "to" : "to_id(firebase refreshedToken)"
} 

これをアプリに追加すると、以下のコードをアクティビティに追加して呼び出すことができます。

<intent-filter>
                <action android:name="OPEN_ACTIVITY_1" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

インテントをどこに作成し、特定のアクティビティを開くようにしますか?OPEN_ACTIVITY_1インテントがマニフェストに登録されていることはわかっていますが、実際にはどこに呼び出しますか?
Cyogenos 2016年


インテントフィルターからアクティビティを呼び出す必要がありますか?または手動で起動しonMessageReceivedますか?
CoolMind

14

onMessageReceived(RemoteMessage remoteMessage)メソッドは、以下の場合に基づいて呼び出されます。

  • FCM応答通知し、データブロック:
{
  
"to": "device token list",
  "notification": {
    "body": "Body of Your Notification",
    "title": "Title of Your Notification"
  },
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}
  1. フォアグラウンドのアプリ:

onMessageReceived(RemoteMessage remoteMessage)が呼び出され、LargeIconとBigPictureが通知バーに表示されます。通知データブロックの両方からコンテンツを読み取ることができます

  1. バックグラウンドでのアプリ:

onMessageReceived(RemoteMessage remoteMessage)は呼び出されません。システムトレイはメッセージを受信し、通知ブロックから本文とタイトルを読み取り、通知バーにデフォルトのメッセージとタイトルを表示します。

  • データブロックのみのFCM応答

この場合、jsonから通知ブロックを削除します

{
  
"to": "device token list",
  "data": {
    "body": "Body of Your Notification in Data",
    "title": "Title of Your Notification in Title",
    "key_1": "Value for key_1",
    "image_url": "www.abc.com/xyz.jpeg",
    "key_2": "Value for key_2"
  }
}

onMessageReceived()を呼び出すためのソリューション

  1. フォアグラウンドのアプリ:

onMessageReceived(RemoteMessage remoteMessage)が呼び出され、LargeIconとBigPictureが通知バーに表示されます。通知データブロックの両方からコンテンツを読み取ることができます

  1. バックグラウンドでのアプリ:

onMessageReceived(RemoteMessage remoteMessage)が呼び出されました。通知に応答キーがないため、システムトレイはメッセージを受信しません。通知バーにLargeIconとBigPictureを表示します

コード

 private void sendNotification(Bitmap bitmap,  String title, String 
    message, PendingIntent resultPendingIntent) {

    NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
    style.bigPicture(bitmap);

    Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

    NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    String NOTIFICATION_CHANNEL_ID = mContext.getString(R.string.default_notification_channel_id);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "channel_name", NotificationManager.IMPORTANCE_HIGH);

        notificationManager.createNotificationChannel(notificationChannel);
    }
    Bitmap iconLarge = BitmapFactory.decodeResource(mContext.getResources(),
            R.drawable.mdmlogo);
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mContext, NOTIFICATION_CHANNEL_ID)
            .setSmallIcon(R.drawable.mdmlogo)
            .setContentTitle(title)
            .setAutoCancel(true)
            .setSound(defaultSound)
            .setContentText(message)
            .setContentIntent(resultPendingIntent)
            .setStyle(style)
            .setLargeIcon(iconLarge)
            .setWhen(System.currentTimeMillis())
            .setPriority(Notification.PRIORITY_MAX)
            .setChannelId(NOTIFICATION_CHANNEL_ID);


    notificationManager.notify(1, notificationBuilder.build());


}

参照リンク:

https://firebase.google.com/docs/cloud-messaging/android/receive


バックグラウンドの問題に苦しんでいる人にとって最も重要な部分は、サーバーから送信されているJSONから「通知」プロパティを削除することです。これで問題が解決します。どうもありがとう。
Ramy M. Mousa

13

同じ問題が発生しました。アプリがフォアグラウンドの場合、バックグラウンドサービスがトリガーされ、通知タイプに基づいてデータベースを更新できます。ただし、アプリはバックグラウンドになります。デフォルトの通知サービスは、ユーザーに通知を表示するように注意されます。

これが、バックグラウンドでアプリを識別してバックグラウンドサービスをトリガーするための私のソリューションです。

public class FirebaseBackgroundService extends WakefulBroadcastReceiver {

  private static final String TAG = "FirebaseService";

  @Override
  public void onReceive(Context context, Intent intent) {
    Log.d(TAG, "I'm in!!!");

    if (intent.getExtras() != null) {
      for (String key : intent.getExtras().keySet()) {
        Object value = intent.getExtras().get(key);
        Log.e("FirebaseDataReceiver", "Key: " + key + " Value: " + value);
        if(key.equalsIgnoreCase("gcm.notification.body") && value != null) {
          Bundle bundle = new Bundle();
          Intent backgroundIntent = new Intent(context, BackgroundSyncJobService.class);
          bundle.putString("push_message", value + "");
          backgroundIntent.putExtras(bundle);
          context.startService(backgroundIntent);
        }
      }
    }
  }
}

manifest.xml内

<receiver android:exported="true" android:name=".FirebaseBackgroundService" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </receiver>

このソリューションを最新のAndroid 8.0バージョンでテストしました。ありがとう


このFirebaseBackgroundServiceクラスを使用するのは何ですか?@Nagendra Badiganti

どこにこのコードパブリッククラスFirebaseBackgroundServiceを使用するWakefulBroadcastReceiver @Nagendra Badiganti拡張

パッケージにサービスクラスを作成し、manifest.xmlに登録します。通知用のフィルターがあることを確認してください。サービスはすべてのGCM通知に対してトリガーされるため。
Nagendra Badiganti 2017年

firebase.google.com/docs/cloud-messaging/android/…このリンクをたどっています。このクラスを追加して通知を受け取る必要があります。firebaseの最初のメッセージからメッセージを送信するだけです。完了しましたが、通知を受信して​​いません。@ Nagendra Badiganti

1
WakefulBroadcastReceiverAPIレベル26.1.0以降では非推奨です。
Minoru

12

アプリがバックグラウンドモードまたは非アクティブ(killed)であり、[ 通知]クリックした場合、LaunchScreenでペイロードを確認する必要があります(私の場合、起動画面はMainActivity.javaです)。

そうでMainActivity.javaのonCreateのためのチェックエクストラ

    if (getIntent().getExtras() != null) {
        for (String key : getIntent().getExtras().keySet()) {
            Object value = getIntent().getExtras().get(key);
            Log.d("MainActivity: ", "Key: " + key + " Value: " + value);
        }
    }

通知のタイトル、本文、およびデータを取得するにはどうすればよいですか?
Md.Tarikul Islam 2018

1
ありがとう、これが答えです。@ Md.Tarikulこの質問で述べられているようにonMessageReceived()を使用するイスラム。
felixwcf

7

handleIntentのためにFirebaseMessageService作品の方法を上書きします。

ここでC#のコード(Xamarin)

public override void HandleIntent(Intent intent)
{
    try
    {
        if (intent.Extras != null)
        {
            var builder = new RemoteMessage.Builder("MyFirebaseMessagingService");

            foreach (string key in intent.Extras.KeySet())
            {
                builder.AddData(key, intent.Extras.Get(key).ToString());
            }

            this.OnMessageReceived(builder.Build());
        }
        else
        {
            base.HandleIntent(intent);
        }
    }
    catch (Exception)
    {
        base.HandleIntent(intent);
    }
}

そしてそれはJavaのコードです

public void handleIntent(Intent intent)
{
    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);
    }
}

handleIntent()は最終版です
Ettore

@EttoreどうすればhandleIntent関数を呼び出すことができますか?
ヒロト

このメソッドは、Firebaseからメッセージを受信したときに呼び出されますが、メソッドがfinalとして宣言されているため、オーバーライドできません。(Firebase 11.6.0)
Ettore

5

デフォルトでは、アプリのランチャーアクティビティは、アプリがバックグラウンドで通知をクリックすると起動されます。通知を含むデータ部分がある場合は、次のように同じアクティビティで処理できます。

if(getIntent().getExtras()! = null){
  //do your stuff
}else{
  //do that you normally do
}

mainActivityからナビゲートする場合、特定のアクティビティに戻るにはどのように機能しますか?
Mac_Play 2018年

@Uzair getIntent()。getExtras()は常にnullを取得します。他に解決策はありますか?アプリが暗転しているときに、onMessageReceivedメソッドが呼び出されません
user2025187

3

アプリがバックグラウンドでFire-baseに設定されている場合、デフォルトで通知を処理しますが、カスタム通知が必要な場合は、カスタムデータ(データペイロード)を送信するサーバー側を変更する必要があります。

サーバー要求から通知ペイロードを完全に削除します。データのみを送信し、onMessageReceived()で処理します。それ以外の場合、アプリがバックグラウンドにあるか強制終了されている場合、onMessageReceivedはトリガーされません。

これで、サーバー側のコード形式は次のようになります。

{
  "collapse_key": "CHAT_MESSAGE_CONTACT",
  "data": {
    "loc_key": "CHAT_MESSAGE_CONTACT",
    "loc_args": ["John Doe", "Contact Exchange"],
    "text": "John Doe shared a contact in the group Contact Exchange",
    "custom": {
      "chat_id": 241233,
      "msg_id": 123
    },
    "badge": 1,
    "sound": "sound1.mp3",
    "mute": true
  }
}

:上記のコードの
「テキスト」のこの行を参照してください。「ペイロード」の「John DoeがグループContact Exchangeの連絡先を共有しました」メッセージの説明などでは、「body」または「message」パラメータの代わりに「text」パラメータを使用する必要がありますテキストを使いたい。

onMessageReceived()

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.e(TAG, "From: " + remoteMessage.getData().toString());

        if (remoteMessage == null)
            return;

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

            try {

                Map<String, String> params = remoteMessage.getData();
                JSONObject json = new JSONObject(params);
                Log.e("JSON_OBJECT", json.toString());


                Log.e(TAG, "onMessageReceived: " + json.toString());

                handleDataMessage(json);
            } catch (Exception e) {
                Log.e(TAG, "Exception: " + e.getMessage());
            }
        }
    }

2

MainActivityのonCreateメソッドでこれを呼び出すだけです。

if (getIntent().getExtras() != null) {
           // Call your NotificationActivity here..
            Intent intent = new Intent(MainActivity.this, NotificationActivity.class);
            startActivity(intent);
        }

mainActivityからナビゲートする場合、特定のアクティビティに戻るにはどのように機能しますか?
Mac_Play 2018年

2

t3h Exiのソリューションによると、ここにクリーンなコードを投稿したいと思います。それをMyFirebaseMessagingServiceに入れるだけで、アプリがバックグラウンドモードの場合はすべて正常に動作します。少なくともcom.google.firebase:firebase-messaging:10.2.1をコンパイルする必要があります

 @Override
public void handleIntent(Intent intent)
{
    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);
    }
}

私はあなたのソリューションを実装しようとしていますが、handleIntent()メソッドは私のSDKバージョン(SDK 27)で最終なので、サービスでオーバーライドできません...
matdev

はい、それは私のせいではなく、-1を与える理由でもありません。とても傲慢です。これは、firebase 11.4.2まで機能し、その後googleが変更しました(このメソッドをfinalにしました)。したがって、通知を使用して独自のソリューションをプログラムする必要があります。
フランク

私は-1ではなく+1を与えました!
matdev

あなたは私の仕事を保存します:P
amitabha2715

2

これを試して:

public void handleIntent(Intent intent) {
    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);
    }
}

handleIntentは、firebase:11.8.0以降では使用されなくなりました。
Shihab Uddin

1

私はこの問題(アプリがバックグラウンドまたは閉じている場合、通知クリックでアプリが開かない)があり、問題はclick_action通知本文で無効でした。削除するか、有効なものに変更してみてください。


1

強調表示に値する点は、アプリがバックグラウンドにある場合でも、onMessageReceivedハンドラーを呼び出すために、データメッセージ(データキーのみ)を使用する必要があることです。ペイロードには他の通知メッセージキーを含めないでください。そうしないと、アプリがバックグラウンドにある場合にハンドラーがトリガーされません。

これはここで言及されています(FCMドキュメントではそれほど強調されていません)。

https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

アプリサーバーとFCMサーバーAPIを使用する:データキーのみを設定します。折りたたみ可能または折りたたみ不可のいずれかです。


1

私が使用しているバックエンドは、データメッセージではなく通知メッセージを使用しています。そのため、すべての回答を読んだ後、起動したアクティビティに到達するインテントのバンドルからエキストラを取得しようとしました。しかし、どのキーから取得しようgetIntent().getExtras();としても、値は常にnullでした。

しかし、ようやく通知メッセージを使用してデータを送信し、インテントからデータを取得する方法を見つけました。

ここで重要なのは、通知メッセージにデータペイロードを追加することです。

例:

{
    "data": {
        "message": "message_body",
        "title": "message_title"
    },
    "notification": {
        "body": "test body",
        "title": "test title"
    },
    "to": "E4An.."
}

これを実行すると、次の方法で情報を取得できるようになります。

intent.getExtras().getString("title") になります message_title

そして、 intent.getExtras().getString("message") なりますmessage_body

参照


1

問題が大きな画像の表示に関連している場合、つまり、Firebaseコンソールからの画像を含むプッシュ通知を送信していて、アプリがフォアグラウンドにある場合にのみ画像を表示します。この問題の解決策は、データフィールドのみを含むプッシュメッセージを送信することです。このようなもの:

{ "data": { "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg", "message": "Firebase Push Message Using API" "AnotherActivity": "True" }, "to" : "device id Or Device token" }

「AnotherActivity」の前にカンマを失った。私のアンドロイドは振動しますが、実際には何も表示されません(テキスト、画像、プッシュなし)。
jekaby

1

メッセージが受信され、アプリがバックグラウンドにある場合、通知はメインアクティビティのエクストラインテントに送信されます。

メインアクティビティのoncreate()またはonresume()関数で追加の値を確認できます。

データ、テーブルなどのフィールド(通知で指定されたもの)を確認できます

たとえば、データをキーとして送信しました

public void onResume(){
    super.onResume();
    if (getIntent().getStringExtra("data")!=null){
            fromnotification=true;
            Intent i = new Intent(MainActivity.this, Activity2.class);
            i.putExtra("notification","notification");
            startActivity(i);
        }

}

0

私は同じ問題を抱えていて、これについてもう少し掘り下げました。アプリがバックグラウンドにある場合、通知メッセージは、システムトレイに送信されますが、データメッセージがに送られるonMessageReceived()
参照https://firebase.google.com/docs/cloud-messaging/downstream#monitor-token-generation_3を
https://github.com/firebase/quickstart-android/blob/master/messaging/app/src/main/java/com/google/firebase/quickstart/fcm/MyFirebaseMessagingService.java

送信するメッセージを確実にするために、ドキュメントには「アプリサーバーとFCMサーバーAPIを使用する:データキーのみを設定します。折りたたみ可能または折りたたみ不可のいずれかを設定できます。」を
参照してください。https://firebase.google.com/ docs / cloud-messaging / concept-options#notifications_and_data_messages


0

メッセージには、通知メッセージとデータメッセージの2種類があります。データメッセージのみを送信する場合は、メッセージ文字列に通知オブジェクトは含まれません。アプリがバックグラウンドで起動したときに呼び出されます。


0

@Mahesh Kavathiyaの回答を確認してください。私の場合、サーバーコードでは次のようなものしかありません:

{
"notification": {
  "body": "here is body",
  "title": "Title",
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

次のように変更する必要があります。

{
 "data": {
  "body": "here is body",
  "title": "Title",
  "click_action": "YOUR_ACTION"
 },
"notification": {
  "body": "here is body",
  "title": "Title"
 },
 "to": "sdfjsdfonsdofoiewj9230idsjkfmnkdsfm"
}

次に、バックグラウンドのアプリの場合、デフォルトのアクティビティインテントエクストラは「データ」を取得します

幸運を!


-1

FirebaseMessagingServiceのOnCreateメソッドをオーバーライドするだけです。アプリがバックグラウンドにあるときに呼び出されます:

public override void OnCreate()
{
    // your code
    base.OnCreate();
}

この回答は、説明を追加したり、いくつかのドキュメントにリンクしたりする場合に役立ちます。これがどのように役立つと思われますか?
キロカーン

@kilokahn理解できないことを説明してくれませんか?示されたメソッドは、質問の一部であり、質問に完全に回答するコードに挿入する必要があります。コードはXamarin用ですが、Javaで簡単に変換できます。
Renzo Ciot

私の知る限りは、公式ドキュメントは(firebase.google.com/docs/cloud-messaging/android/client)FirebaseMessagingServiceを拡張するサービスにOnCreate関数をオーバーライドについて話しません-あなたは、おそらくあなたは、リンクを共有することができないドキュメントへのアクセス権を持っている場合は?また、あなたの答えから、通知がクリックされたときにonCreateをオーバーライドするとonMessageReceivedが呼び出されない問題を解決する方法が明確ではないため、詳細情報のリクエストが必要になります。
キロカーン2018

ドキュメントではOnCreateメソッドのオーバーライドについては触れられていませんが、本番環境で使用しているため機能します。onMessageReceivedメソッドに挿入するコードで、バックグラウンド操作を実行するために役立つコードは、OnCreateで実行できます。
Renzo Ciot

その場合、それが何らかの形で機能したという事実を詳しく説明すると、ソリューションを一覧表示するだけでなく、さらに役立つ場合があります。また、文書化されていない動作は、更新の処理を恣意的に停止する可能性があり、更新を使用する場合は、更新時にコードを再作成する準備をする必要があります。これに置くことに免責事項ニーズ。
kilokahn

-1

ある2種類Firebaseのプッシュ通知は:

1-通知メッセージ(メッセージの表示)->-1.1このバリアントを選択すると、アプリがバックグラウンドで実行されている場合、OSが通知を自動的に作成し、データをに渡しますintent。その後、このデータを処理するのはクライアント次第です。

-1.2アプリがフォアグラウンドにある場合、通知はを介しcallback-functionて受信FirebaseMessagingServiceされ、クライアントが処理する必要があります。

2-データメッセージ(最大4kデータ)->これらのメッセージは、データのみをクライアントに送信(サイレント)するために使用され、コールバック関数を介してバックグラウンド/フォアグラウンドの両方のケースでデータを処理するのはクライアント次第です。 FirebaseMessagingService

これは公式ドキュメントによると:https : //firebase.google.com/docs/cloud-messaging/concept-options

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.