์๋ค! ์ด๋ฒ ์ ๋ฌด๋ rn์ ํธ์ฌ์๋ฆผ์ ์ธํ ํ๋ ๊ฑธ์ธ
..
.. ์ค์ผ์ด ...
firebase์์ ์ง์ํ๋ ํธ์์๋ฆผ ๊ธฐ๋ฅ์ธ cloud messaging์ ์ธํ
ํด๋ณด์. ์ง์ซ ์์ฐํ ์ด๊ฑฐ ์ธํ
ํ
์คํธํ๋ฉด์ ๋ด ๋ช
์ค์ด ์กฐ๊ธ ์ค์ด๋ ๊ฑฐ ๊ฐ๋ค.
ios์ ๊ฒฝ์ฐ๋ ๋ด ๊ฒฝํ์ผ๋ก ์ฑ ์คํ ์ด์ ๋ฐฐํฌ๋ ๊ฒฝ์ฐ์ ํธ์์๋ฆผ์ด ์ ๋๋ก ์๋ํ๋ ๋ฏํ๋ค. ๋ง์ฝ ์๋๋ผ๋ฉด, ๋๊ธ๋ก ๊ฐํ ๋ฐ๋ฐ ๋ถํํ๋ค.
rn FCM ๋ฌธ์
rn FCM api ๋ฌธ์
fcm์ ์ธํ
ํ๋ ค๊ณ ํ๋ ๋น์ , firebase์ @react-native-firebase/app
์ ๋๋ ์ด๋ฏธ ์ค์น๊ฐ ๋์ด์๊ฒ ์ฃ ?
android๋ ๊ฐ๋จํ ํธ์ธ๋ฐ, ios๋ Noti ์ธํ
์ด android์ ๋นํด ์ด๋ ค์ด ํธ์ธ๋ฐ, ๋ง์์ ์ค๋น๋ ๋์ด์์ผ์๊ฒ ์ฃ ?
ios์ ๊ฐ๋ฐ์ ์์ด๋๋ ์๊ฒ ์ฃ ? ios ๊ฐ๋ฐ์ ๊ณ์ ๊ฒฐ์ ๋ ํด๋จ์ ๊ฑฐ๊ตฌ์?
ios Bundle ID๋ ์์๊ฑฐ์์? ์์์ ๋งํ๋ฏ ์ฑ์คํ ์ด์ ๋ฐฐํฌ๋ ํด๋์๊ฒ ์ฃ ?
ios provisioning profile๋ ์์๊ฑฐ์์? ๋ง์ฃ ?
๊ทธ๋ฐ ์ํฉ์ ์ ์ ๋ก ์์ํฉ์๋ค.
npm i @react-native-firebase/messaging
cd ios/ && pod install
์ฐ์ ios๊ฐ android์ ๋นํด ๋ณต์กํ ํธ์ด๋ ios๋ถํฐ ๋ง์คํฐ ํ์.
๊ทธ๋ฌ๋ฉด ์๋๋ก์ด๋๋ ์ ์๋ํ๊ณ ์์ ํ
๋ ๋ง์ด๋ค.
์ฐธ๊ณ : https://rnfirebase.io/messaging/usage/ios-setup
ios ํธ์๋ฉ์์ง๋ฅผ ํ์ฑํ ํ๋ ค๋ฉด ์๋ ๋จ๊ณ๊ฐ ํ์ํ๋ค.
- xcode ์์ ํ๊ธฐ
- APN key ์์ฑ (apple push notification)
- APN๊ณผ FCM ์ฐ๊ฒฐ
- Identifiers ์์
- Profile ์์
(1) Signing & Capabilities ํญ์์ Capability๋ฅผ ๋๋ฅธ๋ค.
(2) Background Modes์ Push Notifications๋ฅผ ํ์ฑํ ์ํค๊ณ , Background Modes๋ ์๋์ ๊ฐ์ด ์ฒดํฌํ๋ค.
(1) Certificates, Identifiers & Profiles๋ก ์ด๋ํด์ ์งํํ๋ค.
(2) Identifiers์ Profiles, Keys๋ฅผ ์์ ํ ๊ฑฐ๋ค.
(3) key ๋ฑ๋กํ๊ธฐ
keys ํญ์ผ๋ก ์ด๋ํด์, ์๋ก์ด ํค๋ฅผ ์์ฑํ๋ค. ๋๋ ์ด๋ฒ ํธ์ ์๋ฆผ์ ํ๊ธฐ ์ ์ key๋ฅผ ์์ฑํ ์ ์ ์๊ณ ์ด๋ฒ์ด ์ฒ์ ์์ฑํ key ์๋ค.
key name์ ๋์ถฉ FCM APNs Key๋ก ์ง์๊ณ ,
Apple Push Notifications service๋ฅผ ๋๋ฌ์ continue๋ฅผ ๋๋ฅธ๋ค. ๊ทธ ๋ค์ ํ์ด์ง๋ ํ์ผ์ ๋ค์ด๋ก๋ ํ ์ ์๊ฒ ๋์ด ์๊ณ , key Id๋ฅผ ๋ณด์ฌ์ค๋ค. ๋ค์ด๋ก๋๋ ํ๋ฒ ๋ฐ์ ๋ชปํ๋ฏ๋ก ์ ๊ด๋ฆฌํด๋๋ค.
์์งํ ์ ๋ชป๊ด๋ฆฌํด์ ์ญ์ ๋์ด๋ ๋ค์ ์์ฑํ๋ ๊ฑด ์ด๋ ต์ง ์๋ค.
firebase์ ์์ฑํ APN ํค๋ฅผ ์ฐ๊ฒฐํด๋ณด์
ํ๋ก์ ํธ ์ค์ > ํด๋ผ์ฐ๋ ๋ฉ์์ง์ผ๋ก ์ด๋ํ์.
๊ฑฐ๊ธฐ์ iOS ์ฑ ๊ตฌ์ฑ > APN ์ธ์ฆ ํค ์ ์๊น ๋ค์ด๋ก๋ ํ ํ์ผ์ ์ฌ๋ฆฌ๋ฉด ๋๋ค.
key ID๋ ๊ฐ์ด ์ ์ด์ฃผ๊ณ , ํ ID๋ ํ๋ก์ ํธ์ ์ด๋ฏธ ์ค์ ๋์ด ์๋ ํ ID๊ฐ ๊ฐ์ ธ์ ์ง๋ค.
Certificates, Identifiers & Profiles > Identifiers์ ๋ค์ด๊ฐ์ Edit์ ๋๋ฌ ์์ ์ ํด๋ณด์.
Capabilities ์๋์ Push Notifications๋ฅผ ํ์ฑํ ํ๊ณ , save๋ฅผ ๋๋ฌ ๋ง๋ฌด๋ฆฌ ํ์.
Push Notifications ์์ Edit์ด๋ผ๊ณ ์ธ์ฆ์๋ฅผ ์ถ๊ฐ ํ ์ ์๋ ๋ฒํผ์ด ์๋๋ฐ, ์์ด๋ ์๋ฌด ๋ฌธ์ ์๋ค. ๊ฑด๋ค์ด์ง ์์๋ ์๋ฌด ์๊ด์๋ค.
Identifiers๋ฅผ ์์ ํ์ผ๋, Certificates, Identifiers & Profiles > Profiles ๋ก ๋ค์ด๊ฐ๋ฉด EXPIRATION์ด Invalid ๋์ด์์ ๊ฒ์ด๋ค. Profile๋ค์ Edit, save๋ฅผ ํด์ค์ ์๋กญ๊ฒ ๊ฐฑ์ ํด์ค๋ค.
๋ฌผ๋ก xcode์์์ provisioning profile๋ ์๋กญ๊ฒ ๋ค์ด๋ก๋ ํด์ค์ผ ๊ฒ ์ง!
์ด๊ฒ์ด apple developer console์์ ํด์ผํ๋ ์ ๋ถ!
ios, android์ ์ฝ๋๊ฐ ๊ฐ๊ธฐ ๋๋ฌธ์ ๊ฐ์ด ์์ ์ ๋ฐ์๋ณด์.
// index.js
import { AppRegistry } from 'react-native';
import messaging from '@react-native-firebase/messaging';
import App from './App';
// Register background handler
messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log('Message handled in the background!', remoteMessage);
});
AppRegistry.registerComponent('app', () => App);
์์ setBackgroundMessageHandler ํจ์๋ ์ฑ์ด active ๋์ด์์ง ์์๋ ์๋ํ๋ค.
๋จ, android์์๋ง ์๋ํ๊ณ , ios์์๋ console ๊ฐ์ด ๋์ค์ง ์๋๋ค. ์ด ํจ์๊ฐ ์์ผ๋ฉด warning์ด ๋จ๊ธฐ ๋๋ฌธ์ ๊ผญ ์ถ๊ฐํด๋์.
import {useEffect} from 'react';
import messaging from '@react-native-firebase/messaging';
function CloudMessaging() {
useEffect(() => {
requestUserPermission();
}, []);
async function requestUserPermission() {
const authorizationStatus = await messaging().requestPermission();
// ๊ถํ์ํ (-1: ์์ฒญ ์ํจ, 0: ๊ฑฐ๋ถ, 1: ์๋ฝ, 2: ์์๊ถํ)
switch (authorizationStatus) {
case 0:
checkToken();
break;
case 1:
// ํ ํฐ ์์ฒญ
checkToken();
// ์ฑ ๊บผ์ ธ์์ ๋
messaging()
.getInitialNotification()
.then((remoteMessage) => handleCloudMsg(remoteMessage));
// background์์๋ง ์๋
messaging().onNotificationOpenedApp((remoteMessage) => {
handleCloudMsg(remoteMessage);
});
break;
default:
break;
}
}
// ํ ํฐ ์์ฒญ: ์ถํ ํ์ํ ์์
function checkToken() {
messaging()
.getToken()
.then((data) => {
console.log('token:', data, messaging().apnsToken);
});
}
async function handleCloudMsg(remoteMessage) {
if (remoteMessage) {
if (remoteMessage.data.articleId){
// ๋ด๊ฐ ์ํ๋ ์ก์
์ด ์๋ํ๊ฒ ํ๊ธฐ
}
}
}
return null;
}
export default CloudMessaging;
์ฑ์ด ์์ ๊บผ์ ธ์์ ๋๋ getInitialNotification ํจ์๋ก
์ฑ์ด background์ ์์ ๋๋ onNotificationOpenedApp ํจ์๋ก
cloud messaging ๋ฐ์ดํฐ๋ฅผ ์์ ๋ฐ๊ฒ ํ๋ค.
์ด๋ ๊ฒ firebase console ํ์ด์ง์ cloudmessaging์ ์ด์ฉํด์ ํ
์คํธ ํด๋ณด๋ฉด
์ฑ๊ณต์ ์ผ๋ก ๋๋ค.
์๋ ์ด๋ ๊ฒ ๊ธ๋ก ์ฐ๋๊น ์์ฒญ ๊ฐ๋จํด ๋ณด์ด๋๋ฐ, ์์ฒญ๋ ์ฝ์ง์ ๊ฒฐ๊ณผ๋ฌผ์ด์๋ค.
๋ด์ผ ์ค์ ์ ์ด์ํ์ด๋ ํ
์คํธ ์๋๋ฐ, ์ค๋ฅ ์๊ธธ..๐
(์ถ๊ฐ)
+ios ํ
์คํธ ์ค, ํธ์์๋ฆผ์ ์ด๋ฏธ์ง๊ฐ ๋ค์ด๊ฐ์ง ์๋ ์ ๋ฐ๊ฒฌ.
ios ํธ์์๋ฆผ์์ ์ด๋ฏธ์ง ๋ณด์ด๊ฒ ํ๋ ์์
์ถ๊ฐ
์ฐธ๊ณ : https://rnfirebase.io/messaging/ios-notification-images
์๋๋ก์ด๋์์๋ ๋ฐ๋ก ์ค์ ํ ํ์ ์๊ณ , ios์์๋ง ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
xcode์์ ์์
์ ํ๋ค.
xcode๋ฅผ ์คํํด์ File > New > Target... ์ ๋๋ฅธ๋ค.
๊ฑฐ๊ธฐ์ Notification Service Extension์ ์ฐพ์์ ์ ํํ๋ค.
๋ญ๊ฐ ์ฑ์์ผ ํ๋ ํ๋ฉด์ด ๋ฐ๊ฑฐ๋ค. ๊ฑฐ๊ธฐ์ Product Name๊ณผ Language๋ฅผ ์์ ํด์ฃผ๋ฉด ๋๋ค. firebase ๋ฌธ์์์ Product Name๋ฅผ ImageNotification์ผ๋ก ์์๋ฅผ ๋ค๊ธธ๋, ๊ณ ๋๋ก ํ๊ณ , Language๋ swift๊ฐ default์ธ๋ฐ Objective-c๋ก ์์ ํ๋ค.
xcode์ ์ผ์ชฝ navigator์์ podfile์ ์ฝ๋๋ค.
์ ์ผ ํ๋จ์ ์๋ ์ฝ๋๋ฅผ ๋ถ์ฌ ๋ฃ์ต๋๋ค.
VERSION_NUMBER ๋ถ๋ถ์ Podfile.lock ํ์ผ์ - Firebase/Messaging (~>
๋ฅผ ๊ฒ์ํ๋ฉด ๊ทธ ๋ค์ ์ซ์๋ฅผ ์ ์ด ๋ฃ์ผ๋ฉด ๋๋ค. ๋๋ 7.4.0์ด์๋ค.
์์ ํ๊ณ pod install์ ์๋ก ํด์ฃผ์ด pod ํ์ผ์ด ๋ฐ์๋๊ฒ ํ๋ค.
target 'ImageNotification' do
pod 'Firebase/Messaging', '~> VERSION_NUMBER' # eg 6.31.0
end
xcode์ ์ผ์ชฝ navigator์์ ImageNotification > NotificationService.m์ ์ฝ๋๋ค.
์ฝ๋ ์ถ๊ฐ ๋ฐ ์์ ํ๊ธฐ
#import "NotificationService.h" // ์๋ ์๋ ์ฝ๋
#import "FirebaseMessaging.h" // ์ถ๊ฐํ๊ธฐ
...
// ์๋์ ์๋ ์๋ ์ฝ๋ ์ญ์ ํ๊ธฐ
- self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];
- self.contentHandler(self.bestAttemptContent);
// ์ ์ฝ๋ ์ญ์ ํ๊ณ , ์๋ ์ฝ๋๋ก ์ถ๊ฐํ๊ธฐ
[[FIRMessaging extensionHelper] populateNotificationContent:self.bestAttemptContent withContentHandler:contentHandler];
ํธ์ ์๋ฆผ์ ๋ ๋ฆฌ๋ฉด ์ด๋ฏธ์ง๊ฐ ์ด์๊ฒ ๋ค์ด๊ฐ๋ค.
General > Identity > Version
๊ณผ General > Identity > Build
๋ฅผ ๊ฐ๊ฒ ํด์ผ ํ๋ค. ์ฌ์ค ์ด๊ฑด App Store๋ก ๋ฐฐํฌ์์ ํ์ํ ์์
์ด๋ค. TestFlight๋ก ๋ณด๋ผ ๋ ๋ ๋ฒ์ ์ด ๋ง์ง ์์ผ๋ฉด Warning์ด ๋ฌ๋ค.(์ถ๊ฐ)
iOS ํธ์์๋ฆผ ์ธํ
์ ํ๊ณ ๋ฌ๋๋ AdHoc์์ ๋งํ๋ฒ๋ ธ๋ค. ๋ณธ๊ธ์ ์์ ์ ํด์ ์ถ๊ฐ๋ฅผ ํ๊ธฐ๋ก ํ์ง๋ง, ๋ฐ๋ก ๊ธ์ ์์ฑํด ๋๊ธฐ๋ ํ๋ค.
https://velog.io/@dody_/RN-์๋ฌ๋
ธํธ-ios-notification-service-extension-์ธํ
-ํ-provisioning-profile์ด-ํ์ํ๋ค
์๋์ ๊ฐ์ ํ์ธํด๋ด๋ ๋๊ณ , ์๋ ๊ธ์ ์ฐธ๊ณ ํด๋ ๋๋ค.
์์์ ์ญ ๋ฐ๋ผ ๋ด๋ ค์ค๋ค๊ฐ, adhoc์ผ๋ก export ํ๋ ค ํ๋ฉด ์๋์ ๊ฐ์ด ๋์จ๋ค.
์๋ oheadline.app์ provisioning profile๋ก adhoc์ด ๋์์๋๋ฐ,
ImageNotification.appex์ provisioning profile๋ select ํด์ผ๋๋ค.
ํ๋๊ฐ ๋ ์ถ๊ฐ ๋๋ค.
๋ฌธ์์๋ ๊ด๋ จ ์ค๋ช
์ด ์์ด์ ์กฐ๊ธ ํค๋งธ๋๋ฐ,
๊ตฌ๊ธ์ ios notification service extension provisioning profile๋ฅผ ์ณ๋ณด๋
๋ค์ํ ์ฌ๋๋ค์ด ์ธ์ฆ์, ํ๋ก๋น์ ๋ ํ๋กํ์ผ์ ์๋ก ๋ง๋ค์ด์ผ ํ๋์ง์ ๋ํด ์ง๋ฌธ์ ๋ง์ด ๋์ก๊ณ ,
๊ทธ์ ๋ํ ๋ต์ผ๋ก ์๋ ๊ธ์ ๋ฐ๊ฒฌํ๊ฒ ๋์๋ค.
https://stackoverflow.com/questions/47466759/do-i-require-distribution-provisioning-profile-for-notification-service-extensio
Identifier, provisioning profile์ ์๋ก ๋ง๋ค์ด์ผ ํ๋ ๋ฏํ๋ค.
์ export ํด์ app distribution์ผ๋ก ํ์ธํด๋ณด๋ ์ฑ๋ ์ ์ค์น๊ณ ๋๊ณ ์๋ฆผ์ ์ด๋ฏธ์ง๋ ์ ๋ค์ด๊ฐ๋๋ผ!
์ง์ง์ง์ง ์ ๋ฐ ๋๐ฅ๐ฅ๐ฅ