계획에 없었지만, 된다고 해서 해본 푸시 알림에 이미지 넣어서 보내는 방법.
일단 안드로이드의 경우에는 특별히 해줄 것이 없다. 그냥 메시지 전송할 때 이미지 URL을 넣어서 보내주기만 하면 된다.
Firebase Console 에서는 테스트 메시지 발송할 때 Notification image 필드에 이미지 URL을 넣어주면 되고,
Firebase API를 이용해서 서버에서 발송할 경우에는 메시지를 아래와 같이 구성해주면 된다.
message = {
notification: {
body: 'This is an FCM notification that displays an image!',
title: 'FCM Notification',
},
android: {
notification: {
image: '{image-url}',
},
},
};
그 다음으로 iOS가 문제인데, iOS에서 이미지가 포함된 푸시메시지를 보여주기 위해서는 service extension을 만들어야 한다.
xcode에서 File > New > Target 선택한 후에 타겟 종류 고르는 dialog 에서 iOS, Notification Service Extension 찾아서 선택해준다.
이름은 아무거나 해 줘도 되는데, 가이드에 있는 것처럼 ImageNotification으로 해주고,
Language는 Objective-C로 골라준다. (Runner는 swift로 만들었어도 Objective-C 로 만든 extension을 사용하는데 문제 없다.)
추가된 ImageNotification Extension에 만들어진 NotificationService.m 파일을 다음과 같이 수정한다.
#import "NotificationService.h"
#import "FirebaseMessaging.h"
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@end
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
// Modify the notification content here...
// self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];
//
// self.contentHandler(self.bestAttemptContent);
[[FIRMessaging extensionHelper] populateNotificationContent:self.bestAttemptContent withContentHandler:contentHandler];
}
- (void)serviceExtensionTimeWillExpire {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
self.contentHandler(self.bestAttemptContent);
}
@end
다음으로 Podfile 에
target 'ImageNotification' do
use_frameworks!
pod 'Firebase/Messaging'
end
를 추가해주면 된다.
여기까지가 Firebase에서 제공하는 가이드의 끝인데, 이 다음에 고생을 좀 했다.
1. 빌드 실패
FirebaseMessaging.h file not found 에러가 나면서 빌드가 되지 않을 때는 Pod 파일들을 지우고 다시 설치해준다.
Podfile.lock 와 Pods 디렉토리를 지우는 것 만으로는 정상동작 하지 않을 수 있다.
> sudo gem install cocoapods-deintegrate cocoapods-clean
> pod deintegrate
> pod cache clean --all
> flutter clean
> rm Podsfile.lock
> rm -rf Pods
> flutter pub get
> pod install
나의 경우에는 이렇게 프로젝트에서 CocoaPods를 제거했다가 다시 설치하니 FirebaseMessaging.h file not found 문제가 해결되었다.
또 다른 문제로 빌드가 안 될 때 ImageNotification 의 Build Settings 메뉴에서 Enable Bitcode 를 No 로 설정하라는 말도 있는데, 나의 경우에는 Yes로 설정해도 빌드에 문제가 없었다.
몇 가지 영향을 줄 수 있는 설정을 보자면 (TARGET을 ImageNotification 으로 설정한 것에 주의하자)
2. 시뮬레이터에서 빌드 실패
위의 1번 과정을 거친 후에 실제 디바이스에서는 빌드가 되지만 시뮬레이터에서는 안 된다면 Runner에서처럼 ImageNotification Target에서도 Excluded Architectures에 arm64와 i386을 추가해준다.
3. 빌드는 되지만 푸시 메시지에 이미지가 노출되지 않을 때
정상적으로 빌드가 되었으나 푸시 메시지에 이미지가 노출되지 않으면
1) 메시지에 이미지를 올바르게 넣어서 보냈는지 확인 (아래 메시지 샘플 확인)
2) 안드로이드에서는 정상적으로 동작하는지 확인
3) ImageNotification 의 Deployment 대상 확인 : General 탭에서 Deployment Info 에 iOS 버전이 Runner와 맞게 되어 있는지 확인한다. 이 값이 테스트하는 디바이스보다 크게 되어 있으면 이미지가 보이지 않는다.
이렇게 하면 메시지에 이미지가 같이 표시된다.
단, 안드로이드에서 Foreground 일 때는 알림을 flutter_local_notifications 패키지를 사용해서 별도로 표시해줬기 때문에 역시 별도로 처리해줘야 한다.
이것은 다음에 기회 되면 포스트하기로 하고,
아래는 Firebase API를 이용해서 이미지가 포함된 메시지 전송할 때 메시지 파라미터이다.
[iOS에서 Push notificatin에 이미지 추가]
message = {
notification: {
body: 'This is an FCM notification that displays an image!',
title: 'FCM Notification',
},
apns: {
payload: {
aps: {
'mutable-content': 1, // 1 or true
},
},
fcm_options: {
image: '{image-url}',
},
},
};
[iOS, 안드로이드 모두 한번에 이미지 넣어서 전송]
message = {
tokens: registrationTokens,
notification: {
body: 'This is an FCM notification that displays an image!',
title: 'FCM Notification',
},
apns: {
payload: {
aps: {
'mutable-content': 1,
},
},
fcm_options: {
image: '{image-url}',
},
},
android: {
notification: {
image: '{image-url}',
},
},
};
아래는 참고한 reference
https://documentation.onesignal.com/docs/notification-images-not-showing