파이어베이스(FCM): 액티비티 열기 및 알림 클릭 시 데이터 전달. 안드로이드
Firebase 알림 및 데이터 작업 방법에 대한 명확한 구현이 있어야 합니다.나는 많은 답을 읽었지만 그것이 작동하지 않는 것 같습니다.내 단계는 다음과 같습니다.
1.) PHP로 안드로이드에게 알림과 데이터를 전달하고 있는데, 괜찮은 것 같습니다.
$msg = array
(
"body" => $body,
"title" => $title,
"sound" => "mySound"
);
$data = array
(
"user_id" => $res_id,
"date" => $date,
"hal_id" => $hal_id,
"M_view" => $M_view
);
$fields = array
(
'registration_ids' => $registrationIds,
'notification' => $msg,
'data' => $data
);
$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 );
2.) Android에서 알림 및 데이터를 수신하면 알림이 표시됩니다.이 알림을 클릭하면 앱이 열립니다.하지만 앱을 열었을 때 데이터를 처리하는 방법을 알 수 없습니다.앱이 전경과 배경에 있을 때 몇 가지 차이점이 있습니다.제가 지금 가지고 있는 코드는 다음과 같습니다.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String user_id = "0";
String date = "0";
String cal_id = "0";
String M_view = "0";
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
user_id = remoteMessage.getData().get("user_id");
date = remoteMessage.getData().get("date");
hal_id = remoteMessage.getData().get("hal_id");
M_view = remoteMessage.getData().get("M_view");
}
//Calling method to generate notification
sendNotification(remoteMessage.getNotification().getBody(), user_id, date, hal_id, M_view);
}
private void sendNotification(String messageBody, String user_id, String date, String hal_id, String M_view) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("fcm_notification", "Y");
intent.putExtra("user_id", user_id);
intent.putExtra("date", date);
intent.putExtra("hal_id", hal_id);
intent.putExtra("M_view", M_view);
int uniqueInt = (int) (System.currentTimeMillis() & 0xff);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), uniqueInt, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setSmallIcon(R.drawable.ic_launcher)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}}
3.) 위의 코드를 사용할 때 알림을 모두 클릭하면 백그라운드에서 앱이 열립니다.앱이 포그라운드에서 알림을 클릭하면 알림이 해제됩니다.그러나 데이터를 수신하고 두 시나리오(배경 및 전경) 모두에서 특정 활동을 열고 싶습니다.기본 활동에 다음 코드가 있지만 데이터를 가져올 수 없습니다.fcm_notification, date, hal_id가 null을 반환합니다.
public class MainActivity extends Activity {
UserFunctions userFunctions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
Intent intent_o = getIntent();
}
@Override
protected void onResume() {
super.onResume();
userFunctions = new UserFunctions();
if(userFunctions.isUserLoggedIn(getApplicationContext())){
Intent intent_o = getIntent();
String fcm_notification = intent_o.getStringExtra("fcm_notification") ;
String user_id = intent_o.getStringExtra("user_id");
String date = intent_o.getStringExtra("date");
String hal_id = intent_o.getStringExtra("hal_id");
String M_view = intent_o.getStringExtra("M_view");
Intent intent = new Intent(this, JobList.class);
// THIS RETURNS NULL, user_id = null
System.out.print("FCM" + user_id);
startActivity(intent);
finish();
}else{
// user is not logged in show login screen
Intent login = new Intent(this, LoginActivity.class);
startActivity(login);
// Closing dashboard screen
finish();
}
}}
만약 누군가가 지시하거나 조언을 해줄 수 있다면, 어떻게 하면 파이어베이스에서 메인액티비티.java의 데이터를 (전경 또는 배경) 검색할 수 있을까요? 그것은 환상적일 것입니다.
먼저 메시지 처리 문서에 언급된 세부 사항을 입력하겠습니다.
Both 행 아래의 요약에서 앱이 포그라운드에 있을 때 페이로드가 처리된다는 것을 보여줍니다.onMessageReceived().
다에서활열려에서 .onMessageReceived()필요한 데이터가 페이로드에 있는지 확인하고, 필요한 경우 특정 활동에 전화를 걸어 다른 모든 세부 정보를 의도를 통해 전달해야 합니다.
이제 앱이 백그라운드에 있는 경우 문서에 안드로이드 시스템 트레이에 의해 알림이 수신되고 다음과 같이 언급됩니다.data페이로드는 의도의 추가 항목에서 검색할 수 있습니다.
여기에 제 답변의 세부 사항을 추가하면 문서 명세서와 샘플에 대한 링크가 거의 제공됩니다.
백그라운드 앱에서 알림 메시지 처리
앱이 백그라운드에 있을 때 Android는 알림 메시지를 시스템 트레이로 보냅니다.사용자가 알림을 누르면 기본적으로 앱 시작 프로그램이 열립니다.
여기에는 알림 및 데이터 페이로드(알림 콘솔에서 보내는 모든 메시지)가 모두 포함된 메시지가 포함됩니다.이 경우 알림은 장치의 시스템 트레이로 전달되고 데이터 페이로드는 실행기 활동의 의도에 따라 추가로 전달됩니다.
저는 @Arthur Thompson의 이 대답이 그것을 매우 잘 설명한다고 생각합니다.
데이터 페이로드(알림 및 데이터)가 포함된 알림 메시지를 보내고 앱이 백그라운드에 있는 경우 사용자가 알림을 탭한 결과로 실행되는 추가 의도에서 데이터를 검색할 수 있습니다.
알림을 누를 때 기본 활동을 시작하는 FCM 샘플에서 다음을 수행합니다.
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
Log.d(TAG, "Key: " + key + " Value: " + value);
}
}
모든 답과 블로그를 시도한 후에 해결책이 나왔습니다.필요한 사람이 있으면 이 비디오를 참조하십시오.
https://www.youtube.com/watch?v=hi8IPLNq59o
My Firebase Messaging Service에서 추가할 비디오 외에도 다음과 같이 추가할 수 있습니다.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String user_id = "0";
String date = "0";
String hal_id = "0";
String M_view = "0";
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
user_id = remoteMessage.getData().get("user_id");
date = remoteMessage.getData().get("date");
cal_id = remoteMessage.getData().get("hal_id");
M_view = remoteMessage.getData().get("M_view");
}
String click_action = remoteMessage.getNotification().getClickAction();
//Calling method to generate notification
sendNotification(remoteMessage.getNotification().getBody(), remoteMessage.getNotification().getTitle(), user_id, date, hal_id, M_view, click_action);
}
private void sendNotification(String messageBody, String messageTitle, String user_id, String date, String hal_id, String M_view, String click_action) {
Intent intent = new Intent(click_action);
intent.putExtra("user_id", user_id);
intent.putExtra("date", date);
intent.putExtra("hal_id", hal_id);
intent.putExtra("M_view", M_view);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}}
그리고 새로운 NotificationCreate 또는 Resume에서 수신 활동을 추가합니다.
notification_Y_N = (TextView) findViewById(R.id.notification_Y_N);
user_id_text = (TextView) findViewById(R.id.user_id_text);
Intent intent_o = getIntent();
String user_id = intent_o.getStringExtra("user_id");
String date = intent_o.getStringExtra("date");
String hal_id = intent_o.getStringExtra("hal_id");
String M_view = intent_o.getStringExtra("M_view");
notification_Y_N.setText(date);
user_id_text.setText(hal_id);
을 onMessageReceived()method 알림을 보내기 위해 다른 방법을 사용해야 합니다(예: 알림을 보내기 위한 웹 API 만들기).그리고 나서 그걸 사용하면,
FCM 메시지에서 알림 페이로드를 제거하여 데이터 페이로드가 메소드로 전달되도록 합니다.
때 는 앱이백운있때을데페다전가다송니됩으로 됩니다.onMessageReceived메서드는 알림 페이로드가 없는 경우에만 사용됩니다.
두 페이로드가 모두 존재하는 경우 시스템은 자동으로 알림 부분(시스템 트레이)을 처리하고 앱은 실행기 활동(사용자가 알림을 누른 후)의 추가적인 데이터 페이로드를 가져옵니다.
자세한 내용은 다음 링크를 참조하십시오.
는 없습니다.sendNotification그리고.onMessageReceived네 자신.
보낼 때:
$data = array
(
"user_id" => $res_id
//whatever fields you want to include
);
$msg = array
(
"body" => $body,
"title" => $title,
"data" => $data
// more fields
);
쪽 (의 안드이당쪽드 (신쪽로쪽당))MainACtivity:
private void handleIntent(Intent intent) {
String user_id= intent.getStringExtra("user_id");
if(user_id!= null)
Log.d(TAG, user_id);
}
그리고 물론:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handleIntent(getIntent());
}
입력한 필드가 무엇이든data 것입니다.extra.
먼저, 응답에 데이터 개체와 알림 개체가 있는 경우 백엔드 개발자에게 알림 개체를 제거하도록 요청합니다.나는 내 수업이 도움이 되길 바랍니다.
public class MyFirebaseService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
Log.d(TAG, "Message data payload:id " + remoteMessage.getData().get("mode_id"));
sendNotification(remoteMessage.getData().get("body"),
remoteMessage.getData().get("mode_id"), remoteMessage.getData().get("click_action"));
}
}
private void sendNotification(String messageBody, String id, String clickAction) {
Intent intent = new Intent(clickAction);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(intent);
intent.putExtra("id", id);
intent.putExtra("body", messageBody);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "111")
.setSmallIcon(R.drawable.venus_logo)
.setContentText(messageBody)
.setAutoCancel(true)
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000})
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentIntent(pendingIntent)
.setLights(Color.GREEN, 3000, 3000);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel notificationChannel = new NotificationChannel("111", "NOTIFICATION_CHANNEL_NAME", importance);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setShowBadge(false);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
assert notificationManager != null;
notificationBuilder.setChannelId("111");
notificationManager.createNotificationChannel(notificationChannel);
notificationManager.notify(0, notificationBuilder.build());
} else {
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(0, notificationBuilder.build());
}
}
}
매니페스트 파일에 추가합니다.
<service
android:name=".data.services.MyFirebaseService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<activity
android:name=".ui.notifications.NotificationsDetailsActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:parentActivityName=".ui.home.HomeActivity"
android:taskAffinity="">
<intent-filter>
<action android:name="co.example.yourApp.ui.notifications_TARGET_NOTIFICATION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Firebase 설명서에는 작동 방식을 설명하는 훌륭한 표가 있습니다.
https://firebase.google.com/docs/cloud-messaging/android/receive#handling_messages
따라서 데이터와 알림이 모두 있고 앱이 수신될 때 전경에 있다면 서비스에서 알림을 직접 생성하여 확장해야 합니다.FirebaseMessagingService(에)onMessageReceived방법)
다른 경우(앱이 백그라운드에 있음)에서 데이터를 가져올 수 있습니다.intent.extras의Activity앱의 기본 활동을 열기 위해 시스템에 의해 알림이 생성됩니다.
언급URL : https://stackoverflow.com/questions/40181654/firebase-fcm-open-activity-and-pass-data-on-notification-click-android
'programing' 카테고리의 다른 글
| 하위 쿼리를 사용하는 SQL 쿼리는 두 쿼리를 개별적으로 사용하는 것보다 더 오래 걸립니다. (0) | 2023.07.11 |
|---|---|
| Git 저장소에서 선택한 커밋 로그 항목을 변경 사항을 유지하면서 제거하는 방법은 무엇입니까? (0) | 2023.07.11 |
| 마스터 푸시에서 Git 트리거를 사용하여 젠킨스 CI를 만들려면 어떻게 해야 합니까? (0) | 2023.07.11 |
| 파이어베이스 업데이트 대 세트 (0) | 2023.07.11 |
| R에서 작업하는 동안 모든 패키지 분리 (0) | 2023.07.11 |
