Firebase에서 백그라운드에서 앱을 사용할 때 알림을 처리하는 방법


426

여기 내 매니페스트

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

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

앱이 백그라운드에 있고 알림이 도착하면 기본 알림이 표시되고 코드가 실행되지 않습니다 onMessageReceived.

여기 내 onMessageReceived코드가 있습니다. 백그라운드에서 앱이 아닌 앱이 포 그라운드에서 실행중인 경우 호출합니다. 앱이 백그라운드에있을 때이 코드를 실행하는 방법은 무엇입니까?

// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // If the application is in the foreground handle both data and notification messages here.
    // 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.
    data = remoteMessage.getData();
    String title = remoteMessage.getNotification().getTitle();
    String message = remoteMessage.getNotification().getBody();
    String imageUrl = (String) data.get("image");
    String action = (String) data.get("action");
    Log.i(TAG, "onMessageReceived: title : "+title);
    Log.i(TAG, "onMessageReceived: message : "+message);
    Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
    Log.i(TAG, "onMessageReceived: action : "+action);

    if (imageUrl == null) {
        sendNotification(title,message,action);
    } else {
        new BigPictureNotification(this,title,message,imageUrl,action);
    }
}
// [END receive_message]

1
두 번째 주석 줄은 onMessageReceived ()재정의 샘플로 작성되었습니다 Not getting messages here? See why this may be: goo.gl/39bRNJ . 이 솔루션은 답변 아래처럼의 문서에서 찾을 수 있습니다 모두 통지 및 데이터 페이로드와 메시지
fllo

간단히 말해서, 종료 된 앱을 깨우려면 항상 응용 프로그램에서 알림 서비스 클래스 핸들러 FirebaseMessagingService.onMessageReceived ()를 호출하기 위해 데이터 객체와 함께 알림을 보내야합니다. 또한 Firebase 콘솔에서 보내지 말고 다른 곳에서 게시하십시오 (예 : 온라인 테스트 사후 서비스).
Zon

1
이 솔루션은 나를 위해 일했습니다 . stackoverflow.com/a/44150822/6632278 희망이 도움이됩니다. 행운을 빌어 요
Tony Barajas

무슨 ".fcm." PshycoFirebaseMessagingServices가 매니페스트에 있습니까? 클래스의 오류를 찾을 수 없습니다.이 매개 변수의 첫 번째 부분을 찾을 수 없습니다.
Éder Rocha Bezerra

답변:


660

1. 왜 이런 일이 발생합니까?

FCM에는 두 가지 유형의 메시지 (Firebase Cloud Messaging)가 있습니다.

  1. 메시지 표시 :이 메시지 onMessageReceived()는 앱이 켜져있을 때만 콜백을 트리거합니다 포 그라운드에
  2. 데이터 메시지 : 앱이 포 그라운드 / 백그라운드 /onMessageReceived() 킬링 상태 인 경우 에도이 메시지로 인해 콜백

참고 : Firebase 팀은 data-messages아직 기기 로 보낼 UI를 개발하지 않았습니다. 이 유형을 보내려면 서버를 사용해야합니다!



2. 어떻게?

이를 위해서는 POST다음 URL에 대한 요청을 수행해야합니다 .

POST https://fcm.googleapis.com/fcm/send

헤더

  • 키 : Content-Type , 값 : application/json
  • 키 : Authorization , 값 : key=<your-server-key>

주제를 사용하는 본문

{
    "to": "/topics/my_topic",
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     }
}

또는 특정 기기로 보내려면

{
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     },
    "registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
}


참고 : 당신이있어 반드시 추가하지 JSON 키 notification
: 참고 는 중포 기지 콘솔에서 찾을 수 있습니다, 서버 키를 얻으려면 :Your project -> settings -> Project settings -> Cloud messaging -> Server Key

3. 푸시 알림 메시지를 처리하는 방법은 무엇입니까?

수신 된 메시지를 처리하는 방법은 다음과 같습니다.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String myCustomKey = data.get("my_custom_key");

     // Manage data
}

4
다음 단계에 따라 동일한 알림에서 "데이터"및 "알림"키를 보낼 수 있습니다. stackoverflow.com/a/42279260/2734021 :)
Daniel S.

15
Firebase team have not developed a UI to send data-messages to your devices, yet.지난 1 년 동안 이것이 바뀌 었습니까?
Hankrecords

2
@Antonio 앱이 죽었을 때 oreo에서 onMessageReceived가 호출되지 않습니다. 나는 단지 데이터로만 페이로드를 가지고 있습니다. 어떤 업데이트가 있습니까?
Samir Mangroliya

63
앱이 백그라운드에있을 때 onMessageReceived호출되지 않으며 FCM에서 심각한 문제입니다 !!! 또한 답변을 업데이트하십시오.
Muhammad Babar

2
글쎄, 이것은 특정 안드로이드 장치에서 발생하는 것처럼 보입니다. 실제 문제라고 생각하면서 몇 시간을 보냈지 만 아무것도 아닌 것으로 판명되었습니다. 그래서 제 조언은 다른 장치에서 테스트하는 것입니다. 심지어 VM에서 테스트했으며 앱이 종료 된 경우에도 알림을 받았습니다. 나는 단지 누군가의 시간을 절약하기 위해 이것을 말하고 있습니다.
Tarek-Dev

158

다음과 같은 경우 firebase 라이브러리가 onMessageReceived () 를 호출하도록하려면

  1. 포 그라운드의 앱
  2. 백그라운드의 앱
  3. 앱이 종료되었습니다

firebase API 요청에 JSON 키 '알림'을 넣지 말고 대신 '데이터'를 사용해야합니다 (아래 참조).

앱이 백그라운드에 있거나 종료 된 경우 다음 메시지는 onMessageReceived ()를 호출 하지 않으며 알림을 사용자 정의 할 수 없습니다.

{
   "to": "/topics/journal",
   "notification": {
   "title" : "title",
   "text": "data!",
   "icon": "ic_notification"
    }
}

그러나 대신 이것을 사용하면 효과가 있습니다.

{
  "to": "/topics/dev_journal",
   "data": {
       "text":"text",
       "title":"",
       "line1":"Journal",
       "line2":"刊物"
   }
} 

기본적으로 메시지는 데이터 객체와 함께 RemoteMessage 인수에 Map으로 전송되며 여기의 스 니펫에서와 같이 onMessageReceived에서 알림을 관리 할 수 ​​있습니다.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();

     //you can get your text message here.
     String text= data.get("text");


     NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
        // optional, this is to make beautiful icon
             .setLargeIcon(BitmapFactory.decodeResource(
                                    getResources(), R.mipmap.ic_launcher))  
        .setSmallIcon(smallIcon)  //mandatory
      .......
    /*You can read more on notification here:
    https://developer.android.com/training/notify-user/build-notification.html
    https://www.youtube.com/watch?v=-iog_fmm6mE
    */
}

1
Firebase 콘솔에서이를 달성 할 수 있습니까?
koder

@koder, 불행히도 Firebase 콘솔은이를 지원하지 않습니다. curl 또는 postman (chrome plugin)과 같은 firebase에 메시지 게시 요청을 보내려면 도구를 사용해야합니다. firebase 메시지 API 여기에서 문서를 참조하십시오 -firebase.google.com/docs / cloud-messaging / http-server-ref
Teerakiat Chitawattanarat

1
이것이 내가 하루 이상 검색했던 것입니다 ..... 정말 완벽하게 작동했습니다. 데이터의 키 값 쌍이 onMessageReceived ()에서 처리되어 해당 값으로 활동을 시작하는 방법을 설명하면 더 좋습니다.
Boopathi T

25
응용 프로그램이 백그라운드에있을 때 당신의 방법은 잘 작동하지만 응용 프로그램이 죽었을 때 나는 데이터를 수신하지 않습니다
Sanzhar

8
Sanzhar의 동일한 문제. 응용 프로그램이 종료되면 메시지가 표시되지 않습니다.
Giacomo M

104

모든 응답이 불완전한 것처럼 보이지만 앱에 백그라운드가있을 때 데이터가있는 알림을 처리 해야하는 것이 있습니다.

이 단계를 수행하면 앱이 백그라운드에있을 때 알림을 처리 할 수 ​​있습니다.

1. 다음과 같이 인 텐트 필터를 추가하십시오.

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

알림 데이터를 처리하려는 활동에

  1. 다음 형식으로 알림을 보냅니다.

    { 
     "notification" : {
            "click_action" : ".MainActivity", 
            "body" : "new Symulti update !", 
            "title" : "new Symulti update !", 
            "icon" : "ic_notif_symulti" }, 
     "data": { ... },
     "to" : "c9Vaa3ReGdk:APA91bH-AuXgg3lDN2WMcBrNhJZoFtYF9" }

여기서 핵심은 추가

"click_action" : ".MainActivity"

여기서 .MainActivity는 1 단계에서 추가 한 의도 필터가있는 활동입니다.

  1. ".MainActivity"의 onCreate에있는 알림에서 "데이터"정보를 가져옵니다.

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //get notification data info
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
           //bundle must contain all info sent in "data" field of the notification
        }
    }

그리고 그게 당신이해야 할 모든 것입니다. 나는 이것이 누군가를 돕기를 바랍니다 :)


5
이것이 정답이어야합니다. 어떤 문서도 트레이에 알림이 표시되도록 click_action 및 인 텐트 필터를 요구하는 것에 대해 언급하지 않습니다. 둘 다 필요합니다.
airowe

@airowe 그들은 알림을 표시 할 필요가 없습니다
AlwaysConfused

데이터 블록과 알림 블록이 모두 있지만 활동중인 데이터를 수신 할 수 없습니까?
Ashwani

3
나는 이것이 어떻게 받아 들여지는 대답이 아닌지 이해하지 못합니다. click_action이 없으면 작동하지 않습니다. 내 하루를
Arun Shankar

4
@ArunShankar에 감사드립니다. 수락 된 답변은 7 개월 전에 답변을 받았고 좋은 답변이었습니다. 아무도 click_action에 대해 이야기하지 않는 이유를 이해할 수 없으므로 답변을 추가했습니다. 나는 그것이 많은 사람들에게 매우 유용하고 그것이 하루가 끝날 무렵 중요한 일이라는 것을 매우 기쁘게 생각합니다 :)
Daniel S.

42

firebase를 사용하여 다운 스트림 전송 에있는 firebase 문서에 따르면 두 가지 유형의 페이로드가 있습니다.

  1. 데이터

    이 매개 변수는 메시지 페이로드의 사용자 정의 키-값 쌍을 지정합니다. 클라이언트 앱은 데이터 메시지 처리를 담당합니다. 데이터 메시지에는 사용자 정의 키-값 쌍만 있습니다.

  2. 공고

    이 매개 변수는 통지 페이로드의 사전 정의 된 사용자 표시 키-값 쌍을 지정합니다. FCM은 클라이언트 앱 대신 최종 사용자 장치에 메시지를 자동으로 표시합니다. 알림 메시지에는 사전 정의 된 사용자 표시 키 세트가 있습니다.

포 그라운드에있을 때 onMessageReceived ()를 사용하여 FCM 내부 의 데이터를 얻을 수 있으며 데이터 페이로드 에서 데이터를 가져올 수 있습니다 .

data = remoteMessage.getData();
String customData = (String) data.get("customData");

백그라운드에있을 때 FCM은 알림 페이로드 의 정보를 기반으로 시스템 트레이에 알림을 표시 합니다. 시스템 트레이의 알림에 사용 된 제목, 메시지 및 아이콘은 알림 페이로드 에서 가져옵니다 .

{
  "notification": {
        "title" : "title",
        "body"  : "body text",
        "icon"  : "ic_notification",
        "click_action" : "OPEN_ACTIVITY_1"
       }
}

알림 페이로드는 앱이 백그라운드에있을 때 시스템 트레이에 알림을 자동으로 표시하려는 경우에 사용됩니다. 앱이 백그라운드에있을 때 알림 데이터를 얻으려면 알림 페이로드 내에 click_action을 추가해야합니다 .

앱을 열고 백그라운드에서 특정 작업을 수행하려면 알림 페이로드에서 click_action을 설정하고 시작하려는 활동의 인 텐트 필터에 매핑하십시오. 예를 들어 click_action을 OPEN_ACTIVITY_1로 설정하여 다음과 같이 인 텐트 필터를 트리거하십시오.

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

해당 인 텐트 필터를 활동 태그 중 하나의 매니페스트에 배치하십시오. 알림을 클릭하면 앱이 열리고 click_action에서 정의한 활동 (이 경우 "OPEN_ACTIVTY_1")으로 바로 이동합니다. 그리고 그 활동 내에서 다음을 통해 데이터를 얻을 수 있습니다.

Bundle b = getIntent().getExtras();
String someData = b.getString("someData");

내 안드로이드 앱에 FCM을 사용하고 있으며 두 페이로드를 모두 사용하고 있습니다. 다음은 사용중인 JSON 예제입니다.

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification",
    "click_action" : "OPEN_ACTIVITY_1"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

"애플리케이션 태그 안에 매니페스트에 인 텐트 필터를 넣습니다." 응용 프로그램 태그 안에 인 텐트 필터를 넣을 수 없습니다.
Kyrylo Zapylaiev

JSON dow는 click_action 키의 위치를 ​​표시하지 않습니다.
Josh

이것은 정답이 아닙니다? 클릭 동작이란 무엇입니까? 일부는 투표를 중단하거나 이것을 청소해야합니다
rana

1
@KyryloZapylaiev 방금 답변을 수정하고 업데이트합니다. "인 텐트 필터를 활동 태그 중 하나에 넣으십시오".
Dika

1
@Josh가 업데이트 및 형식화되었습니다. 다시 확인할 수 있습니다
Dika

32

문서 에 따르면

백그라운드 앱에서 메시지 처리

앱이 백그라운드에 있으면 Android는 알림 메시지를 시스템 트레이로 보냅니다. 알림을 사용자가 누르면 기본적으로 앱 실행기가 열립니다.

여기에는 알림 및 데이터 페이로드가 모두 포함 된 메시지가 포함됩니다. 이 경우 알림은 장치의 시스템 트레이에 전달되고 데이터 페이로드는 런처 활동의 의도에 따라 추가로 전달됩니다.

앱을 열고 특정 작업을 수행하려면 알림 페이로드에서 click_action을 설정하고 시작하려는 활동의 인 텐트 필터에 매핑하십시오. 예를 들어 click_action을 OPEN_ACTIVITY_1로 설정하여 다음과 같이 인 텐트 필터를 트리거하십시오.

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

편집하다 :

스레드를 기반으로 :

Firebase 콘솔을 사용하여 click_action 페이로드를 설정할 수 없습니다. curl 명령 또는 사용자 정의 http 서버로 테스트를 시도 할 수 있습니다.

curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>" 
     --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send  
     -d "{\"to\":\"/topics/news\",\"notification\": 
         {\"title\": \"Click Action Message\",\"text\": \"Sample message\",
            \"click_action\":\"OPEN_ACTIVITY_1\"}}"

1
네 말이 맞아 나는 문서를 읽었다. 그러나 나는 이것을 내 매니페스트에 어디에 넣을 지 혼란 스럽습니까? Java 파일의 onMessageReceived에서 코드를 실행해야하므로 무엇을해야합니까?
Parth Patel 2016 년

앱이 백그라운드에있을 때 자동으로 onMessageReveiced를 호출하도록 할 수 없습니다. 대신 수신 된 의도를 처리하고 핸들러가 호출하도록해야합니다. 또는 onMessageReveiced와 의도 처리 모두에서 호출되는 별도의 클래스 / 메소드를 구현하는 것이 가장 좋습니다. 주요 활동의 onNewIntent에 처리기를 추가했으며 나에게 잘 작동합니다.
diidu

@Parath Patel 질문에 응답하기에는 너무 늦었지만 같은 문제를 가진 다른 사람에게 도움이 될 것입니다. 여기에서 내 대답을 살펴보십시오. stackoverflow.com/a/42279260/2734021
Daniel S.

이 행동을 어디에 두어야합니까? 내 활동 또는 Firebasemessage 서비스에 대해
Mahdi

** 여러 알림 리디렉션이 작동하지 않습니까? 예 : "click_action"을 사용하여 백그라운드에서 fcm으로부터 3 개의 알림을받은 경우 첫 번째 알림이 성공적으로 리디렉션 된 후 2 알림 클릭을하면 활동 리디렉션이 작동하지 않습니다
prasanthMurugan

24

2019 년 7 월 현재

Android compileSdkVersion 28, buildToolsVersion 28.0.3 및 firebase-messaging : 19.0.1

다른 모든 StackOverflow 질문과 답변을 조사하고 수많은 구식 솔루션을 시도한 후이 솔루션은 다음 세 가지 시나리오에서 알림을 표시했습니다.

-앱이 포 그라운드에 있습니다.
MyFirebaseMessagingService 클래스의 onMessageReceived 메소드가 알림을받습니다

-앱이 종료되었습니다 (백그라운드에서 실행되지 않음). FCM에 의해 알림이 알림 트레이로 자동 전송됩니다. 사용자가 알림을 터치하면 매니페스트에 android.intent.category.LAUNCHER가있는 활동을 호출하여 앱이 시작됩니다. onCreate () 메소드에서 getIntent (). getExtras ()를 사용하여 알림의 데이터 부분을 가져올 수 있습니다.

-앱이 백그라운드에 있습니다. FCM에 의해 알림이 알림 트레이로 자동 전송됩니다. 사용자가 알림을 터치하면 매니페스트에 android.intent.category.LAUNCHER가있는 활동을 시작하여 앱이 포 그라운드로 이동합니다. 내 응용 프로그램에 해당 활동에 launchMode = "singleTop"가 있으므로 동일한 클래스의 활동 하나가 이미 작성되어 있기 때문에 onCreate () 메소드가 호출되지 않고 해당 클래스의 onNewIntent () 메소드가 호출되어 데이터의 일부를 가져옵니다 intent.getExtras ()를 사용하여 알림.

단계 : 1- 앱의 주요 활동을 다음과 같이 정의한 경우 :

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:screenOrientation="portrait"
    android:launchMode="singleTop">
    <intent-filter>
        <action android:name=".MainActivity" />
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

2- MainActivity.class의 onCreate () 메소드에서이 행을 추가하십시오.

Intent i = getIntent();
Bundle extras = i.getExtras();
if (extras != null) {
    for (String key : extras.keySet()) {
        Object value = extras.get(key);
        Log.d(Application.APPTAG, "Extras received at onCreate:  Key: " + key + " Value: " + value);
    }
    String title = extras.getString("title");
    String message = extras.getString("body");
    if (message!=null && message.length()>0) {
        getIntent().removeExtra("body");
        showNotificationInADialog(title, message);
    }
}

그리고 같은 MainActivity.class에 대한 메소드 :

@Override
public void onNewIntent(Intent intent){
    //called when a new intent for this class is created.
    // The main case is when the app was in background, a notification arrives to the tray, and the user touches the notification

    super.onNewIntent(intent);

    Log.d(Application.APPTAG, "onNewIntent - starting");
    Bundle extras = intent.getExtras();
    if (extras != null) {
        for (String key : extras.keySet()) {
            Object value = extras.get(key);
            Log.d(Application.APPTAG, "Extras received at onNewIntent:  Key: " + key + " Value: " + value);
        }
        String title = extras.getString("title");
        String message = extras.getString("body");
        if (message!=null && message.length()>0) {
            getIntent().removeExtra("body");
            showNotificationInADialog(title, message);
        }
    }
}


private void showNotificationInADialog(String title, String message) {

    // show a dialog with the provided title and message
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();
}

3- 다음과 같이 MyFirebase 클래스를 만듭니다.

package com.yourcompany.app;

import android.content.Intent;
import android.util.Log;

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

public class MyFirebaseMessagingService extends FirebaseMessagingService {


    public MyFirebaseMessagingService() {
        super();
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        Log.d(Application.APPTAG, "myFirebaseMessagingService - onMessageReceived - message: " + remoteMessage);

        Intent dialogIntent = new Intent(this, NotificationActivity.class);
        dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        dialogIntent.putExtra("msg", remoteMessage);
        startActivity(dialogIntent);

    }

}

4- 다음과 같이 새 클래스 NotificationActivity.class를 작성하십시오.

package com.yourcompany.app;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ContextThemeWrapper;

import com.google.firebase.messaging.RemoteMessage;

public class NotificationActivity extends AppCompatActivity {

private Activity context;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    context = this;
    Bundle extras = getIntent().getExtras();

    Log.d(Application.APPTAG, "NotificationActivity - onCreate - extras: " + extras);

    if (extras == null) {
        context.finish();
        return;
    }

    RemoteMessage msg = (RemoteMessage) extras.get("msg");

    if (msg == null) {
        context.finish();
        return;
    }

    RemoteMessage.Notification notification = msg.getNotification();

    if (notification == null) {
        context.finish();
        return;
    }

    String dialogMessage;
    try {
        dialogMessage = notification.getBody();
    } catch (Exception e){
        context.finish();
        return;
    }
    String dialogTitle = notification.getTitle();
    if (dialogTitle == null || dialogTitle.length() == 0) {
        dialogTitle = "";
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(context, R.style.myDialog));
    builder.setTitle(dialogTitle);
    builder.setMessage(dialogMessage);
    builder.setPositiveButton(getResources().getString(R.string.accept), new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            dialog.cancel();
        }
    });
    AlertDialog alert = builder.create();
    alert.show();

}

}

5- 태그 내에서 앱 매니페스트에이 줄을 추가하십시오.

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

    <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id"/>

    <activity android:name=".NotificationActivity"
        android:theme="@style/myDialog"> </activity>

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

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/color_accent" />

6-Application.java onCreate () 메소드 또는 MainActivity.class onCreate () 메소드에 다음 행을 추가하십시오.

      // notifications channel creation
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      // Create channel to show notifications.
      String channelId = getResources().getString("default_channel_id");
      String channelName = getResources().getString("General announcements");
      NotificationManager notificationManager = getSystemService(NotificationManager.class);
      notificationManager.createNotificationChannel(new NotificationChannel(channelId,
              channelName, NotificationManager.IMPORTANCE_LOW));
  }

끝난.

위에서 언급 한 3 가지 시나리오에서이 기능이 제대로 작동하려면 다음과 같은 방식으로 Firebase 웹 콘솔에서 알림을 보내야합니다.

알림 섹션에서 : 알림 제목 = 알림 대화 상자에 표시 할 제목 (선택 사항) 알림 텍스트 = 사용자에게 표시 할 메시지 (필수) 그런 다음 대상 섹션에서 : App = Android 앱 및 추가 옵션 섹션 : Android 알림 채널 = default_channel_id 맞춤 데이터 키 : 제목 값 : (알림 섹션의 제목 필드에있는 동일한 텍스트) 키 : 본문 값 : (알림 섹션의 메시지 필드에있는 동일한 텍스트) 키 : click_action 값 : .MainActivity Sound = 사용 안함
만료 = 4 주

Google Play API 28의 에뮬레이터에서 디버깅 할 수 있습니다.

행복한 코딩!


2
이 위대한 답변에 감사드립니다.
Alex Chengalan

@alvaro, 알림을받을 때 Url을 열려면 처리 방법
engmms

앱이 닫히거나 죽일 때 생체 내 opp 전화에서 작동하지 않음
Android 개발자

나는 Vivo 전화에서 시도하지 않았지만 현재 많은 다른 Android 전화에서 작동하고 있습니다. 모든 단계를 천천히 읽고 모든 세부 사항을 확인한 다음 여기에서 언급 한 각 방법의 첫 번째 줄에서 디버깅 중단 점을 켜고 케이블로 개발 컴퓨터에 실제 전화를 연결하고 전송하는 동안 앱을 디버깅하십시오. FCM으로부터의 메시지. 내가 언급 한 모든 매개 변수와 형식으로 FCM 메시지를 전송하고 있는지 확인하십시오. 행운을 빕니다!
alvaro

2
Firebase 설명서에 다음과 같이 표시되는 가장 최신 답변입니다. 앱이 백그라운드에 있으면 Android가 알림 메시지를 시스템 트레이로 보냅니다. 알림을 사용자가 누르면 기본적으로 앱 실행기가 열립니다. 여기에는 알림 및 데이터 페이로드가 모두 포함 된 메시지가 포함됩니다. 이 경우 알림은 장치의 시스템 트레이에 전달되고 데이터 페이로드는 런처 활동의 의도에 따라 추가로 전달됩니다. ( firebase.google.com/docs/cloud-messaging/android/… ) 너무 오래된 답변이 오래되었습니다
Riot Goes Woof

20

때문에 display-messages어떤 앱이 포 그라운드에있는 경우에만 작동 중포 기지 알림 UI에서 전송됩니다. 의 경우 FCM에data-messages POST 호출을해야합니다.

단계

  1. 고급 휴식 클라이언트 Google 크롬 확장 프로그램 설치 여기에 이미지 설명을 입력하십시오

  2. 다음 헤더를 추가하십시오

    : Content-Type, Value : application / json

    : 인증, : key = "사용자 서버 키" 여기에 이미지 설명을 입력하십시오

  3. 몸을 추가

    • 주제를 사용하는 경우 :

      {
          "to" : "/topics/topic_name",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
          }
      }
    • 등록 ID를 사용하는 경우 :

      {
          "registration_ids" : "[{"id"},{id1}]",
          "data": {
          "key1" : "value1",
          "key2" : "value2",
           }
      }

그게 다야!. 이제 onMessageReceived평소와 같이 콜백을 듣습니다 .

@Override
public void onMessageReceived(RemoteMessage remoteMessage) { 
     Map<String, String> data = remoteMessage.getData();
     String value1 = data.get("key1");
     String value2 = data.get("key2");
}

20

백그라운드에서 메시지를 캡처하려면 BroadcastReceiver

import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.legacy.content.WakefulBroadcastReceiver
import com.google.firebase.messaging.RemoteMessage

class FirebaseBroadcastReceiver : WakefulBroadcastReceiver() {

    val TAG: String = FirebaseBroadcastReceiver::class.java.simpleName

    override fun onReceive(context: Context, intent: Intent) {

        val dataBundle = intent.extras
        if (dataBundle != null)
            for (key in dataBundle.keySet()) {
                Log.d(TAG, "dataBundle: " + key + " : " + dataBundle.get(key))
            }
        val remoteMessage = RemoteMessage(dataBundle)
        }
    }

이것을 매니페스트에 추가하십시오.

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

7
앱이 백그라운드에있을 때 알림 메시지를받습니다. 그러나 기본 Firebase 수신자가 처리하지 못하게하므로 메시지가 여전히 알림 알림으로 표시됩니다.
Galya

현재 작동하지 않으므로이 솔루션을 제안하는 이유입니다. Google 버그베이스에 신고 된 버그가 있습니다. 당신은 그것을 확인하고 싶을 수도 있습니다.
Romulano

여기 버그에 대한 링크를 게시 해 주
시겠습니까?

알림에서 데이터를 얻는 방법?
Ravi Vaghela

앱이 종료되면 분명히 작동하지 않습니다. 나는이 솔루션을 몇 시간 동안 시도했다. 어떤 이유로 든 앱이 백그라운드에있는 동안 리시버가 작동하고 앱이 종료되면 작동하지 않습니다.
XcodeNOOB

16
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

}

앱이 forground에있을 때만 호출 될 때마다 호출되지 않습니다.

포 그라운드 또는 백그라운드 또는 종료 된 앱에 관계없이이 메소드는 매번 호출되는 재정의 메소드가 하나 있지만이 메소드는이 Firebase API 버전에서 사용할 수 있습니다.

이것은 gradle에서 가져와야하는 버전입니다.

compile 'com.google.firebase:firebase-messaging:10.2.1'

이것은 방법입니다

@Override
public void handleIntent(Intent intent) {
    super.handleIntent(intent);

    // you can get ur data here 
    //intent.getExtras().get("your_data_key") 


}

이전 firebase api를 사용하면이 방법이 없었습니다.이 경우 응용 프로그램이 백그라운드에있을 때 fire base handle 자체가 .... 이제 u 원하는 방법을 가지고 있습니다 ... u 여기 에서이 방법으로 할 수 있습니다 .. ...

이전 버전을 사용하는 경우 기본 활동이 시작됩니다.이 경우 u는 동일한 방식으로 데이터를 얻을 수 있습니다.

if(getIntent().getExtras() != null && getIntent().getExtras().get("your_data_key") != null) {
String strNotificaiton = getIntent().getExtras().get("your_data_key").toString();

// 원하는 것을하십시오 ....}

일반적으로 이것은 알림을받는 서버의 구조입니다.

{
    "notification": {
        "body": "Cool offers. Get them before expiring!",
        "title": "Flat 80% discount",
        "icon": "appicon",
        "click_action": "activity name" //optional if required.....
    },
    "data": {
        "product_id": 11,
        "product_details": "details.....",
        "other_info": "......."
    }
}

u가 그 데이터 키를주고 싶거나 u가 줄 수있는 모든 것을 통지하고 싶을 때 U에게 달려 있습니다. 같은 키로 u를 줄 것이라면 그 데이터를 얻을 것입니다. .

u가 알림을 클릭 할 때 클릭 동작을 보내지 않으면 기본 활동이 열립니다. 앱이 백그라운드에있을 때 특정 활동을 열려면 u가 handleIntent 메소드에서 활동을 호출 할 수 있습니다. 매번 호출


firebase-messaging을 10.2.1로 업데이트하고 알림 메시지에 데이터를 추가했는데 작동했습니다. 전경, 배경 및 살해. 감사합니다
Firas Shrourou 2016 년

코 틀린에, 나는이 오류 얻을 : (44, 5) 'FirebaseMessagingService'에서 'handleIntent'을 최종 및 재정의 할 수 없습니다
부드러운 우갈리

그것은
firebase

14

문서에 따르면 : 2017 년 5 월 17 일

앱이 백그라운드 에 있으면 Android는 알림 메시지를 시스템 트레이로 보냅니다. 알림을 사용자가 누르면 기본적으로 앱 실행기 가 열립니다 .

여기에는 알림 및 데이터 페이로드와 알림 콘솔에서 보낸 모든 메시지가 포함 된 메시지가 포함 됩니다. 이 경우 알림은 장치의 시스템 트레이에 전달되고 데이터 페이로드는 런처 활동의 의도에 따라 추가로 전달됩니다.

따라서 페이로드 알림 + 데이터를 모두 사용해야합니다.

{
  "to": "FCM registration ID",
  "notification": {
    "title" : "title",
    "body"  : "body text",
    "icon"  : "ic_notification"
   },
   "data": {
     "someData"  : "This is some data",
     "someData2" : "etc"
   }
}

click_action을 사용할 필요가 없습니다. LAUNCHER 액티비티 에 대한 의도로 시험을 받아야 합니다

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

Java 코드는 MainActivity의 onCreate 메소드에 있어야합니다.

Intent intent = getIntent();
if (intent != null && intent.getExtras() != null) {
    Bundle extras = intent.getExtras();
    String someData= extras.getString("someData");
    String someData2 = extras.getString("someData2");
}

Firebase Notifications Console 에서 페이로드 알림 + 데이터를 모두 테스트 할 수 있습니다 . 고급 옵션 섹션에서 사용자 정의 데이터 필드를 채우는 것을 잊지 마십시오


13

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

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

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

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

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

또한 onMessageReceived방법 (데이터 메시지 참조)을 사용하여 데이터 번들을 추출하는 것이 좋습니다 . 논리에서 번들 객체를 확인했지만 예상되는 데이터 내용을 찾지 못했습니다. 다음은 더 명확한 정보를 제공 할 수있는 유사한 사례에 대한 참조입니다.

자세한 내용은 내 스레드를 방문하십시오.



8

이와 같은 간단한 요약

  • 앱이 실행중인 경우

    onMessageReceived()

트리거입니다.

  • 앱이 실행 중이 아닌 경우 (스 와이프하여 종료);

    onMessageReceived()

direclty에 의해 트리거되고 전달되지 않습니다. 특수 키-값 쌍이있는 경우 onMessageReceived ()가 작동하지 않아 작동하지 않습니다.

나는이 방법을 찾았다.

런처 활동에서이 논리를

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState, R.layout.activity_splash);

    if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("PACKAGE_NAME")) {

        // do what you want

        // and this for killing app if we dont want to start
        android.os.Process.killProcess(android.os.Process.myPid());

    } else {

        //continue to app
    }
}

이 if 블록에서 firebase UI에 따라 키를 검색하십시오.

이 예에서 위의 키와 값은 다음과 같습니다. (언어 = 죄송합니다) 여기에 이미지 설명을 입력하십시오

내 코드가 작동하면 "com.rda.note"가 나타납니다.

android.os.Process.killProcess(android.os.Process.myPid());

이 코드 줄을 사용하여 응용 프로그램을 닫고 Google Play 마켓을 열었습니다.

행복한 코딩 =)


6

시나리오를 알아 냈습니다.

애플 리케이션에있을 때 전경 , onMessageReceived () 메소드에서 호출 FirebaseService 낭포 pendingIntent 호출되는 서비스 클래스에 정의.

응용 프로그램이있을 때 그리고 배경 , 첫 번째 활동 이라고합니다.

당신이 사용하는 경우 이제 시작 활동을 하고 있어야 마음에 계속 splashactivity가 다음 첫 번째 활동이 무엇이든, 호출됩니다 더 splashActivity이 존재하지 않는 경우는 다른, 호출됩니다.

그런 다음 확인해야합니다 () getIntent을firstActivity 는 어떤이 있는지 번들 은 번들이 채워 값이 나타납니다 확실히 모든 잎파리. 만약에 값 데이터 태그 이 같은 서버 외모에서 전송,

"data": {
    "user_name": "arefin sajib",
    "value": "user name notification"
  }

그런 다음 첫 번째 활동에서 유효한 intent ( getIntent ()가 null이 아님 ), 유효한 번들 및 내부 번들이 있으며 위에서 언급 한 전체 JSON이 datakey 로 표시 됩니다 .

이 시나리오에서 가치 추출 코드는 다음과 같습니다.

    if(getIntent()!=null){
            Bundle bundle = getIntent().getExtras();
            if (bundle != null) {
                try {
                   JSONObject object = new JSONObject(bundle.getStringExtra("data"));
String user_name = object.optString("user_name");

                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }
        }

3

답변 해 주셔서 감사합니다. 그러나 Notification 을 보내는 대신 데이터 메시지 를 보내서이 문제를 해결했습니다 . 서버 코드

<?php
$url = "https://fcm.googleapis.com/fcm/send";
$token = "C-l6T_a7HouUK****";
$serverKey = "AAAAaOcKS00:********";
define( 'API_ACCESS_KEY', $serverKey );
$registrationIds = array($token);
// prep the bundle

$msg = array

(
 'message'  => 'here is a message. message',
 'title'        => 'This is a title. title',
 'subtitle' => 'This is a subtitle. subtitle',
 'tickerText'   => 'Ticker text here...Ticker text here...Ticker text 
 here',
 'vibrate'  => 1,
 'sound'        => 1,
 'largeIcon'    => 'large_icon',
 'smallIcon'    => 'small_icon'

);

$fields = array

(
  'registration_ids'    => $registrationIds,
  'data'            => $msg

);
$headers = array

(
  'Authorization: key=' . API_ACCESS_KEY,
 'Content-Type: application/json'

);


$ch = curl_init();

curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' 
);

curl_setopt( $ch,CURLOPT_POST, true );

curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );

curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );

curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );

curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );

$result = curl_exec($ch );

curl_close( $ch );

echo $result;

?>

그리고 onMessageReceived의 데이터를 잡았습니다.

public class MyFirebaseMessagingService extends FirebaseMessagingService     {

  private static final String TAG = "MyFirebaseMsgService";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d(TAG, "From: " + remoteMessage.getFrom());

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

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


}
   private void sendNotification(String messageBody) {
    Intent intent = new Intent(this, Notify.class).putExtra("msg",messageBody);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT);

    String channelId = "idddd";
    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(MyFirebaseMessagingService.this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .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());
}
}

1
배경으로도 작동합니까?
Tabish khan

@Tabishkhan 예 형제 그것은 당신이 어떤 문제가 나에게 물어 주시기 바랍니다 경우 작동합니다 .. thanks
Android Sanaullah

1
안녕하세요 @AndroidSanaullah, 서버 코드의 첫 번째 부분을 설명 할 수 있습니까? 실제로 어디에 넣습니까? 동일한 문제에 직면하고 있지만 서버 부분을 이해하지 못합니다. 우편 배달원을 사용하고 있습니까?
Shid

컬은 그것에 요청에 사용되는 모든 매개 변수가 전달됩니다 @ Shid.
안드로이드 Sanaullah

2

서버 요청에서 알림 페이로드를 완전히 제거하십시오 . 전송 데이터 만 하고 그것을 처리 onMessageReceived()그렇지 않으면, onMessageReceived뜻이 응용 프로그램은 배경 또는 사망에있을 때 트리거 할 수 없습니다.

다음은 서버에서 보내는 것입니다.

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

따라서 다음 onMessageReceived(RemoteMessage message)과 같이 데이터를 수신 할 수 있습니다 (ID를 얻어야한다고 가정 해 봅시다)

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

마찬가지로 서버 내에서 보낸 모든 데이터를 얻을 수 있습니다 onMessageReceived().


2

앱이 백그라운드 및 포 그라운드에있는 경우에도 다음과 같이 메시지를 보내는 쉬운 방법 :-API를 사용하여 메시지를 보내려면 크롬 확장명 인 AdvancedREST 클라이언트라는 도구를 사용하고 다음 매개 변수를 사용하여 메시지를 보낼 수 있습니다.

나머지 클라이언트 도구 링크 : https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo

이 URL을 사용하십시오 : https://fcm.googleapis.com/fcm/send Content-Type : application / json Authorization : key = 귀하의 서버 키 또는 Authoization 키 (아래 참조 참조)

{ "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"
}

인증 키는 Google 개발자 콘솔을 방문하여 프로젝트 왼쪽 메뉴에서 자격 증명 버튼을 클릭하여 얻을 수 있습니다. 나열된 API 키 중 서버 키는 인증 키입니다.

그리고 API를 사용하여 보낸 POST 요청의 "to"섹션에 수신자의 tokenID를 넣어야합니다.


2

백그라운드에서 데이터 부분 알림 부분에서만 onMessageReceived (RemoteMessage remoteMessage)를 작업하려고합니다.

"data":    "image": "",    "message": "Firebase Push Message Using API", 

"AnotherActivity": "True", "to": "장치 ID 또는 장치 토큰"

이 onMessageRecivied는 호출 배경이며 포 그라운드는 실행기 활동에서 알림 트레이를 사용하여 알림을 처리 할 필요가 없습니다. 이것을 사용하여 데이터 페이로드를 처리하십시오.

  public void onMessageReceived(RemoteMessage remoteMessage)
    if (remoteMessage.getData().size() > 0) 
    Log.d(TAG, "Message data payload: " + remoteMessage.getData());      

1

2018 년 6 월 답변-

메시지에 "알림"키워드가 없는지 확인해야합니다. "데이터"만 포함하면 앱이 백그라운드에서 또는 종료 된 경우에도 onMessageReceived의 메시지를 처리 ​​할 수 ​​있습니다.

클라우드 기능 사용 :

const message = {
    token: token_id,   // obtain device token id by querying data in firebase
    data: {
       title: "my_custom_title",
       body:  "my_custom_body_message"
       }
    }


return admin.messaging().send(message).then(response => {
    // handle response
});

그런 다음 onMessageReceived ()에서 com.google.firebase.messaging.FirebaseMessagingService를 확장하는 클래스에서 :

if (data != null) {
  Log.d(TAG, "data title is: " + data.get("title");
  Log.d(TAG, "data body is: " + data.get("body");
}

// build notification using the body, title, and whatever else you want.

소스가 있습니까? 안전합니까?
Yogesh Rathi

안전합니다. 앱에서 사용합니다. 그러나 게시한지 6 개월이 지난 후에는 소스를 기억할 수 없습니다. Firebase 문서 인 것 같습니다.
Jeff Padgett

1

OAUTH 2.0에 따르면 :

FAUC가 OAUTH 2를 사용하고 있으므로이 경우 인증 문제가 발생합니다.

그래서 나는 firebase 문서를 읽고 문서에 따르면 데이터 메시지를 게시하는 새로운 방법은 다음과 같습니다.

POST: https://fcm.googleapis.com/v1/projects/YOUR_FIREBASEDB_ID/messages:send

헤더

Key: Content-Type, Value: application/json

인증

Bearer YOUR_TOKEN 

본문 예

{
   "message":{
    "topic" : "xxx",
    "data" : {
         "body" : "This is a Firebase Cloud Messaging Topic Message!",
         "title" : "FCM Message"
          }
      }
 }

URL에는 Firebase 콘솔에서 데이터베이스 ID를 찾을 수 있습니다. (프로젝트 설정 이동)

이제 토큰을 가져 오십시오 (1 시간 만 유효).

먼저 Firebase 콘솔에서 설정> 서비스 계정을 엽니 다 . 새 개인 키 생성을 클릭 하고 키가 포함 된 JSON 파일을 안전하게 저장하십시오. 서버 요청을 수동으로 승인하려면이 JSON 파일이 필요했습니다. 다운로드했습니다.

그런 다음 node.js 프로젝트를 만들고이 함수를 사용하여 토큰을 얻습니다.

var PROJECT_ID = 'YOUR_PROJECT_ID';
var HOST = 'fcm.googleapis.com';
var PATH = '/v1/projects/' + PROJECT_ID + '/messages:send';
var MESSAGING_SCOPE = 'https://www.googleapis.com/auth/firebase.messaging';
var SCOPES = [MESSAGING_SCOPE];

  router.get('/', function(req, res, next) {
      res.render('index', { title: 'Express' });
      getAccessToken().then(function(accessToken) {
        console.log("TOKEN: "+accessToken)
      })

    });

function getAccessToken() {
return new Promise(function(resolve, reject) {
    var key = require('./YOUR_DOWNLOADED_JSON_FILE.json');
    var jwtClient = new google.auth.JWT(
        key.client_email,
        null,
        key.private_key,
        SCOPES,
        null
    );
    jwtClient.authorize(function(err, tokens) {
        if (err) {
            reject(err);
            return;
        }
        resolve(tokens.access_token);
    });
});
}

이제 게시물 요청에서이 토큰을 사용할 수 있습니다. 그런 다음 데이터 메시지를 게시하면 이제 내 앱 onMessageReceived 함수에서 처리합니다.


허용 대답은 barer 토큰 인증은 방법이 아니다, 노력하고, 당신은 우편 배달부와 그것을 시도이 글을 읽을 필요가 : stackoverflow.com/questions/45309674/...
카를로스 예수 아란 Taborga

1

2019 년 이후 Google Firebase는 API가 크게 변경되었습니다. 'com.google.firebase:firebase-messaging:18.0.0'

18.0.0에서 그들은 제거 MyFirebaseInstanceIDService되었고 토큰 을 가져와야 MyFirebaseMessagingService하므로 다음 과 같이 작성하면됩니다.

@Override
public void onNewToken(String token) {
    Log.d(TAG, "Refreshed token: " + token);

}

또한 AndroidManifest.xml에서 다음을 제거해야합니다.

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

또한 알림 모양을 사용자 정의하기 위해 기본값을 설정하는 것이 좋습니다. 알림 페이로드에서 동등한 값을 설정하지 않을 때마다 적용되는 사용자 정의 기본 아이콘 및 사용자 정의 기본 색상을 지정할 수 있습니다.

응용 프로그램 태그 안에 다음 줄을 추가하여 사용자 정의 기본 아이콘 및 사용자 정의 색상을 설정하십시오.

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

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/push_channel" />

백그라운드 앱에서 알림 메시지를 처리하려면 SplashScreen 인 경우에도 첫 번째 활동에서 인 텐트를 정의해야합니다. 앱이 백그라운드에 있으면 Android가 알림 메시지를 시스템 트레이로 보냅니다. 알림을 사용자가 누르면 기본적으로 앱 실행기가 열립니다.

예를 들어, Json이 다음과 같은 경우 :

 "data": {
"message": "2",
"title": "1",
"pushType" : "banner",
"bannerLink": "http://www.google.com",
"image" : "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"}

그 값을 얻으려면 간단한 의도를 작성하면됩니다.

        Bundle extras = intent.getExtras();
        String bannerLink = extras.getString("bannerLink");
        ...
        String channelId = extras.getString("channelId");

0

위의 답변 외에도 FCM console을 사용하여 푸시 알림을 테스트하는 경우 '데이터'키와 객체가 푸시 알림 번들에 추가 되지 않습니다 . 따라서 앱이 백그라운드이거나 종료 된 경우 자세한 푸시 알림을받지 않습니다.

이 경우 앱 백그라운드 시나리오를 테스트하려면 백엔드 관리 콘솔을 선택해야합니다.

여기에서 푸시 번들에 '데이터'키를 추가했습니다. 자세한 푸시가 예상대로 표시됩니다. 이것이 도움이되기를 바랍니다.


0

이 코드를 사용하면 백그라운드 / 전경에서 알림을 받고 조치를 취할 수 있습니다.

//Data should come in this format from the notification
{
  "to": "/xyz/Notifications",
  "data": {
      "key1": "title notification",
      "key2": "description notification"
  }
}

인앱은 다음 코드를 사용합니다.

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
      String key1Data = remoteMessage.getData().get("key1");
      // use key1Data to according to your need
    }

// {{to ":"/ xyz / Notifications ","data ": {"key1 ":"title notification ","key2 ":"description notification "}} 작성 방법 PHP 서비스 에서이 코드는?
Tabish khan

-3

두 가지 유형의 알림이 있습니다

  1. 디스플레이 알림-디스플레이 알림 만 표시되며 앱이 열려 있지 않고 앱 스택에 표시됩니다.
  2. 데이터 알림-콜백은 firebasemessagingservice의 onMessageReceived 메소드로 이동하며 앱이 백그라운드, 포 그라운드 또는 종료 상태에있을 때 작동합니다.

앱이 백그라운드에있을 때 알림을 처리하려면 데이터 알림을 사용해야합니다.


-5

동일한 문제가 발생하여 Firebase 라이브러리를 다시 컴파일하여 애플리케이션이 백그라운드에있을 때 알림을 보내지 못했습니다.

* 라이브러리 https://github.com/erdalceylan/com-google-firebase-messaging

 dependencies {
        compile 'com.google.firebase:firebase-core:11.2.0'
        compile 'com.github.erdalceylan:com-google-firebase-messaging:v1-11.2.0'
    }

*

@WorkerThread
public void onMessageReceived(RemoteMessage var1) {
  //your app is in background or foreground all time calling
}

희망이 도움이됩니다. 행운을 빕니다


2
쓸모

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