백그라운드에서 앱을 실행할 때 Firebase onMessageReceived가 호출되지 않음


233

Firebase로 작업하고 있으며 앱이 백그라운드에있는 동안 서버에서 내 앱으로 알림을 전송하는 것을 테스트하고 있습니다. 알림이 성공적으로 전송되면 장치의 알림 센터에도 표시되지만 알림이 표시되거나 클릭해도 FCMessagingService 내의 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.


이 글타래를 확인할 수도 있습니다
.

답변:


144

이것은 의도 한대로 작동하며 알림 메시지는 앱이 포 그라운드에있을 때만 onMessageReceived 콜백에 전달됩니다. 앱이 백그라운드에 있거나 닫힌 경우 알림 메시지가 알림 센터에 표시되고 해당 메시지의 모든 데이터 는 사용자가 알림을 탭한 결과 시작되는 의도로 전달됩니다 .

click_action을 지정하여 사용자가 알림을 누를 때 시작하려는 의도를 표시 할 수 있습니다. click_action이 지정되지 않은 경우 기본 활동이 사용됩니다.

의도가 시작되면

getIntent().getExtras();

알림 메시지와 함께 전송 된 모든 데이터를 포함하는 세트를 검색합니다.

알림 메시지에 대한 자세한 내용은 docs를 참조하십시오 .


6
click_actionFirebase 알림 콘솔을 사용할 때 시간 을 설정하는 방법이 있습니까?
Nii Laryea 1

6
좋아,하지만 앱이 종료되면 (포 그라운드 또는 백그라운드 없음)?
michalu 2016 년

3
그러나 사용자 삭제 알림을 비활성화하는 방법은 무엇입니까? 사용자가 삭제하면 모든 데이터를 건너 뜁니다.
Aleksey Timoshchenko

4
옳은! 따라서 Android에 알림 메시지를 보낼 때 수반되는 데이터는 알림 환경을 향상시키는 데이터 여야합니다. 앱 중요 데이터가 아니어야합니다. 사용자가 알림을 해제하더라도 애플리케이션에 필요한 데이터에 데이터 메시지를 사용하십시오.
Arthur Thompson

3
이것은 완전히 정확하지 않습니다. 메시지에 알림 페이로드가 아닌 데이터 만 포함 된 경우 앱이 포 그라운드에 있는지 여부에 관계없이 메시지는 항상 onMessageReceive로 전달됩니다.
JacksOnF1re

125

notification서버 요청에서 필드를 완전히 제거하십시오 . 보내기 data 하고 그것을 처리 onMessageReceived()그렇지 않으면 onMessageReceived()응용 프로그램은 배경 또는 사망에있을 때 의지가 트리거 할 수 없습니다.

"priority": "high"알림 요청에 필드 를 포함시키는 것을 잊지 마십시오 . 문서에 따르면 : 데이터 메시지는 보통 우선 순위로 전송되므로 즉시 도착하지 않습니다. 또한 문제가 될 수 있습니다.

서버에서 보내는 내용은 다음과 같습니다.

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

그래서 당신은 이렇게 데이터를받을 수 있습니다 onMessageReceived(RemoteMessage message).

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

9
데이터 메시지 만 보내면 작업 관리자에서 지워진 앱이 알림을받을 수 없다는 것을 알았습니다. 의도 된 동작입니까?
Prabhjot Singh

2
이것은 백그라운드에서 메시지를 수신하는 솔루션이었습니다!
Ray Hulha

5
앱이 종료 될 때 Oreo에서 onMessageReceived가 호출되지 않습니다. 나는 단지 데이터로만 페이로드를 가지고 있습니다. 어떤 업데이트가 있습니까?
Samir Mangroliya

2
매력처럼 작동합니다!
ssk

3
이 답변에 당신을 많이 사랑합니다 : p
Ahmad Arslan

63

이 메소드 handleIntent ()는 감가 상각되었으므로 다음과 같이 알림 처리를 수행 할 수 있습니다.

  1. 포 그라운드 상태 : 알림 클릭은 일반적으로 알림의 데이터 페이로드로 생성 된대로 프로그래밍 방식으로 알림을 작성하는 동안 제공중인 보류중인 의도의 활동으로 이동합니다.

  2. Background / Killed State-여기에서 시스템 자체는 알림 페이로드를 기반으로 알림을 작성하며 해당 알림을 클릭하면 라이프 사이클 방법에서 인 텐트 데이터를 쉽게 가져올 수있는 애플리케이션의 실행기 활동으로 이동합니다.


감사합니다!!! 나는이 문제로 며칠을 잃었고이 하나는 나를 구했다.
Igor Janković

정말 완벽한 솔루션입니다!
EduXavier

4
handleIntent (Intent intent)에서 알림 표시 논리를 처리하고 있지만 앱이 백그라운드에있을 때 2 개의 알림이 표시됩니다. 하나는 기본적으로 생성되었으며 다른 하나는 기본적으로 알림의 전체 메시지를 포함합니다.
Joyson

5
대단하지만 OnMessageReceived이 경우에는 사용하지 않습니다 !?
Alaa AbuZarifa

8
com.google.firebase : firebase-messaging : 11.6.2 & handleIntent가 최종 완료되었습니다. stackoverflow.com/questions/47308155/…
Ronak Poriya

31

다음은 firebase 메시지에 대한보다 명확한 개념입니다. 지원팀에서 찾았습니다.

Firebase에는 세 가지 메시지 유형이 있습니다 .

알림 메시지 : 알림 메시지는 배경 또는 전경에서 작동합니다. 앱이 백그라운드에 있으면 알림 메시지가 시스템 트레이로 전달됩니다. 앱이 포 그라운드에있는 경우, 메시지가 처리 onMessageReceived()또는 didReceiveRemoteNotification콜백. 본질적으로 디스플레이 메시지라고합니다.

데이터 메시지 : Android 플랫폼에서 데이터 메시지는 백그라운드 및 포 그라운드에서 작동 할 수 있습니다. 데이터 메시지는 onMessageReceived ()에 의해 처리됩니다. 플랫폼 별 참고 사항은 다음과 같습니다. Android의 경우 활동을 시작하는 데 사용 된 의도로 데이터 페이로드를 검색 할 수 있습니다. 당신이있을 경우 정교하게하려면 "click_action":"launch_Activity_1", 당신이 의도를 통해 검색 할 수 있습니다 getIntent()만에서 Activity_1.

알림 및 데이터 페이로드가 모두 포함 된 메시지 : 백그라운드에서 앱은 알림 트레이에 알림 페이로드를 받고 사용자가 알림을 누를 때만 데이터 페이로드를 처리합니다. 포 그라운드에있을 때 앱은 두 페이로드를 모두 사용할 수있는 메시지 객체를받습니다. 둘째, click_action 매개 변수는 종종 데이터 페이로드가 아닌 알림 페이로드에 사용됩니다. 데이터 페이로드 내에서 사용되는 경우이 매개 변수는 사용자 정의 키-값 쌍으로 취급되므로 의도 한대로 작동하도록 사용자 정의 논리를 구현해야합니다.

또한 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 2016 년

5
@ 앱이 백그라운드에 있지 않은 경우 전경에있는 경우에만 작동합니다. 두 경우 모두이 이벤트를 트리거하도록 도와 줄 수 있습니까 ??
Anant Shah

@AnantShah Firebase 서버에 대한 POST는 어떻게 생겼습니까?
Koot

3
실제로 여기에는 세 가지 가능한 경우가 있습니다. 1) 포 그라운드에있는 앱. 백그라운드에서 2) 응용 프로그램. 3) 앱이 실행되지 않습니다. 당신이 말하는 것처럼, '데이터'메시지가 있지만, 처음 두 경우에 수신 될 수 없습니다 응용 프로그램이 실행되지 않는 세 번째 경우이다. 세 가지 경우 모두를 충족 시키려면 메시지에서 '알림'필드를 설정해야합니다. (또한 좋은 아이디어 당신은 아이폰 OS뿐만 아니라 안드로이드 클라이언트를 지원하려는 경우)
스티브 모슬리

1
앱이 실행 중이 아니더라도 메시지 수신 기능에 대해 서버에서 메시지를 가져옵니다. iOS를 지원하려면 '알림'을 사용하는 것이 좋습니다.
Koot

21

Firebase Cloud Messaging 설명서에 따라 활동이 포 그라운드에 있으면 onMessageReceived가 호출됩니다. 활동이 백그라운드에 있거나 닫힌 경우 앱 실행기 활동에 대한 알림 센터에 알림 메시지가 표시됩니다. 앱이 백그라운드에있는 경우 Firebase 메시징 용 나머지 서비스 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 :

firebase.google.com/docs/cloud-messaging/android/… 이 링크를 따라 가면 알림을 받으려면이 클래스를 추가해야합니다. 단지 중포 기지 첫 번째 메시지에서 메시지를 전송 .. 그것을 말한다 완료되었지만 수신하지 통지 @Nagendra Badiganti

1
WakefulBroadcastReceiverAPI 레벨 26.1.0부터 더 이상 사용되지 않습니다.
Minoru

12

앱이 백그라운드 모드 또는 비활성 (사망)에, 당신이 경우 클릭통지 , 당신은 (내 경우 시작 화면입니다 MainActivity.java에서) LaunchScreen의 페이로드를 확인해야한다.

따라서 MainActivity.java 에서 onCreate on Extras를 확인하십시오 .

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

알림 제목, 본문 및 데이터를 얻으려면 어떻게해야합니까?
Md. Tarkul 이슬람

1
고마워, 이것이 답이다. 이 질문에 언급 된대로 onMessageReceived ()를 사용하는 @ Md.Tarikul Islam.
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);
    }
}

그게 자바 코드

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

.? @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
  }
}

참고 : 위 코드
"text" 에서이 행을 참조하십시오 . 데이터 페이로드에서 "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

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이 변경했습니다 (이 방법을 최종적으로 만들었습니다). 따라서 이제 알림으로 자체 솔루션을 프로그래밍해야합니다.
Frank

나는 -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

문제가 Big Image 표시와 관련된 경우 (예 : 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

메시지에는 알림 메시지와 데이터 메시지의 두 가지 유형이 있습니다. 데이터 메시지 만 보내면 메시지 문자열에 알림 개체가없는 것입니다. 앱이 백그라운드에있을 때 호출됩니다.


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

@kilokahn 당신이 이해하지 못하는 것을 나에게 설명해 주시겠습니까? 표시된 방법을 질문의 일부인 코드에 삽입하고 질문에 완전히 답변해야합니다. 코드는 Xamarin 용이지만 Java로 간단히 변환 할 수 있습니다.
Renzo Ciot

AFAIK 공식 문서 ( firebase.google.com/docs/cloud-messaging/android/client )는 FirebaseMessagingService를 확장하는 서비스에서 OnCreate를 재정의하는 것에 대해 이야기하지 않습니다. 문서에 액세스 할 수 있다면 링크를 공유 할 수 있습니까? 또한 귀하의 답변에 따르면 onCreate를 재정의하면 알림을 클릭 할 때 onMessageReceived가 호출되지 않는 문제를 해결하는 방법이 명확하지 않으므로 자세한 정보 요청이 필요합니다.
kilokahn

설명서에는 OnCreate 메서드의 재정의에 대해서는 언급되어 있지 않지만 프로덕션 환경에서 사용하기 때문에 작동합니다. onMessageReceived 메소드에 삽입하고 백그라운드 작업을 수행하는 코드는 OnCreate에서 수행 할 수 있습니다.
Renzo Ciot

이 경우 어떻게 든 효과가 있다는 사실을 자세히 설명하면 솔루션을 나열하는 것보다 더 도움이 될 수 있습니다. 또한 문서화되지 않은 동작으로 인해 업데이트 작업이 임의로 중단 될 수 있으므로 업데이트를 사용하는 사람은 코드를 다시 작성해야합니다. 이 면책 조항을 제출해야합니다.
kilokahn

-1

있다 2 종류중포 기지의 푸시 알림 :

1- 알림 메시지 (디스플레이 메시지)->-1.1이 변형을 선택하면 앱이 백그라운드에있는 경우 OS에서 자체 알림을 작성하고 의 데이터를 전달합니다 intent. 그런 다음이 데이터를 처리하는 것은 클라이언트의 책임입니다.

- 1.2 응용 프로그램이있는 경우 전경 다음을 통해 수신됩니다 알림 callback-functionFirebaseMessagingService와 그것을 처리하기 위해 클라이언트까지입니다.

2- 데이터 메시지 (최대 4k 데이터)->이 메시지는 클라이언트에게만 데이터를 전송하는 데 사용되며 콜백 기능을 통해 백그라운드 / 포 그라운드를 처리하는 것은 클라이언트의 책임입니다. FirebaseMessagingService

공식 문서에 따르면 https://firebase.google.com/docs/cloud-messaging/concept-options

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.