Commit cecf7a60 authored by Libin Lu's avatar Libin Lu

ios v4

parent 60d941f6
......@@ -56,6 +56,16 @@ export default class PushController extends Component {
console.log("TOKEN (refreshUnsubscribe)", token);
this.props.onChangeToken(token);
});
// direct channel related methods are ios only
// directly channel is truned off in iOS by default, this method enables it
FCM.enableDirectChannel();
this.channelConnectionListener = FCM.on(FCMEvent.DirectChannelConnectionChanged, (data) => {
console.log('direct channel connected' + data);
});
setTimeout(function() {
FCM.isDirectChannelEstablished().then(d => console.log(d));
}, 1000);
}
showLocalNotification(notif) {
......
declare module "react-native-fcm" {
type FCMEventType = "FCMTokenRefreshed" | "FCMNotificationReceived";
type FCMEventType = "FCMTokenRefreshed" | "FCMNotificationReceived" | 'FCMDirectChannelConnectionChanged';
export module FCMEvent {
const RefreshToken = "FCMTokenRefreshed";
const Notification = "FCMNotificationReceived";
const DirectChannelConnectionChanged: 'FCMDirectChannelConnectionChanged'
}
export module RemoteNotificationResult {
......@@ -79,6 +80,10 @@ declare module "react-native-fcm" {
static setBadgeNumber(badge: number): void;
static getBadgeNumber(): Promise<number>;
static send(id: string, data: any): void;
static enableDirectChannel(): void
static isDirectChannelEstablished(): Promise<boolean>
static getAPNSToken(): Promise<string>
}
export default FCM;
......
import {NativeModules, DeviceEventEmitter, Platform} from 'react-native';
import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
const EventEmitter = new NativeEventEmitter(NativeModules.RNFIRMessaging);
export const FCMEvent = {
RefreshToken: 'FCMTokenRefreshed',
Notification: 'FCMNotificationReceived'
}
Notification: 'FCMNotificationReceived',
DirectChannelConnectionChanged: 'FCMDirectChannelConnectionChanged'
};
export const RemoteNotificationResult = {
NewData: 'UIBackgroundFetchResultNewData',
NoData: 'UIBackgroundFetchResultNoData',
ResultFailed: 'UIBackgroundFetchResultFailed'
}
};
export const WillPresentNotificationResult = {
All: 'UNNotificationPresentationOptionAll',
None: 'UNNotificationPresentationOptionNone'
}
};
export const NotificationType = {
Remote: 'remote_notification',
NotificationResponse: 'notification_response',
WillPresent: 'will_present_notification',
Local: 'local_notification'
}
};
const RNFIRMessaging = NativeModules.RNFIRMessaging;
......@@ -29,28 +32,41 @@ const FCM = {};
FCM.getInitialNotification = () => {
return RNFIRMessaging.getInitialNotification();
}
};
FCM.enableDirectChannel = () => {
if (Platform.OS === 'ios') {
return RNFIRMessaging.enableDirectChannel();
}
};
FCM.isDirectChannelEstablished = () => {
return Platform.OS === 'ios' ? RNFIRMessaging.isDirectChannelEstablished() : Promise.resolve(true);
};
FCM.getFCMToken = () => {
return RNFIRMessaging.getFCMToken();
};
FCM.getAPNSToken = () => {
if (Platform.OS === 'ios') {
return RNFIRMessaging.getAPNSToken();
}
};
FCM.requestPermissions = () => {
return RNFIRMessaging.requestPermissions();
};
FCM.presentLocalNotification = (details) => {
details.id = details.id || new Date().getTime().toString()
details.id = details.id || new Date().getTime().toString();
details.local_notification = true;
RNFIRMessaging.presentLocalNotification(details);
};
FCM.scheduleLocalNotification = function(details) {
if (!details.id) {
throw new Error("id is required for scheduled notification");
}
if (!details.fire_date) {
throw new Error("fire_date is required for scheduled notification");
throw new Error('id is required for scheduled notification');
}
details.local_notification = true;
RNFIRMessaging.scheduleLocalNotification(details);
......@@ -61,7 +77,7 @@ FCM.getScheduledLocalNotifications = function() {
};
FCM.cancelLocalNotification = (notificationID) => {
if(!notificationID){
if (!notificationID) {
return;
}
RNFIRMessaging.cancelLocalNotification(notificationID);
......@@ -72,35 +88,34 @@ FCM.cancelAllLocalNotifications = () => {
};
FCM.removeDeliveredNotification = (notificationID) => {
if(!notificationID){
if (!notificationID) {
return;
}
RNFIRMessaging.removeDeliveredNotification(notificationID);
}
};
FCM.removeAllDeliveredNotifications = () => {
RNFIRMessaging.removeAllDeliveredNotifications();
}
};
FCM.setBadgeNumber = (number) => {
RNFIRMessaging.setBadgeNumber(number);
}
};
FCM.getBadgeNumber = () => {
return RNFIRMessaging.getBadgeNumber();
}
};
function finish(result){
if(Platform.OS !== 'ios'){
function finish(result) {
if (Platform.OS !== 'ios') {
return;
}
if(!this._finishCalled && this._completionHandlerId){
if (!this._finishCalled && this._completionHandlerId) {
this._finishCalled = true;
switch(this._notificationType){
switch (this._notificationType) {
case NotificationType.Remote:
result = result || RemoteNotificationResult.NoData;
if(!Object.values(RemoteNotificationResult).includes(result)){
if (!Object.values(RemoteNotificationResult).includes(result)) {
throw new Error(`Invalid RemoteNotificationResult, use import {RemoteNotificationResult} from 'react-native-fcm' to avoid typo`);
}
RNFIRMessaging.finishRemoteNotification(this._completionHandlerId, result);
......@@ -110,7 +125,7 @@ function finish(result){
return;
case NotificationType.WillPresent:
result = result || (this.show_in_foreground ? WillPresentNotificationResult.All : WillPresentNotificationResult.None);
if(!Object.values(WillPresentNotificationResult).includes(result)){
if (!Object.values(WillPresentNotificationResult).includes(result)) {
throw new Error(`Invalid WillPresentNotificationResult, make sure you use import {WillPresentNotificationResult} from 'react-native-fcm' to avoid typo`);
}
RNFIRMessaging.finishWillPresentNotification(this._completionHandlerId, result);
......@@ -126,16 +141,21 @@ FCM.on = (event, callback) => {
throw new Error(`Invalid FCM event subscription, use import {FCMEvent} from 'react-native-fcm' to avoid typo`);
};
if(event === FCMEvent.Notification){
return DeviceEventEmitter.addListener(event, async(data)=>{
if (event === FCMEvent.Notification) {
return EventEmitter.addListener(event, async(data) => {
data.finish = finish;
try {
await callback(data);
if(!data._finishCalled){
} catch (err) {
console.error('Notification handler err', err);
throw err;
}
if (!data._finishCalled) {
data.finish();
}
})
});
}
return DeviceEventEmitter.addListener(event, callback);
return EventEmitter.addListener(event, callback);
};
FCM.subscribeToTopic = (topic) => {
......
......@@ -4,7 +4,6 @@
#import <React/RCTUtils.h>
@import UserNotifications;
#import <FirebaseInstanceID/FirebaseInstanceID.h>
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
......@@ -17,6 +16,8 @@
#endif
NSString *const FCMNotificationReceived = @"FCMNotificationReceived";
NSString *const FCMTokenRefreshed = @"FCMTokenRefreshed";
NSString *const FCMDirectChannelConnectionChanged = @"FCMDirectChannelConnectionChanged";
@implementation RCTConvert (NSCalendarUnit)
......@@ -135,6 +136,10 @@ RCT_ENUM_CONVERTER(UNNotificationPresentationOptions, (@{
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE();
- (NSArray<NSString *> *)supportedEvents {
return @[FCMNotificationReceived, FCMTokenRefreshed, FCMDirectChannelConnectionChanged];
}
+ (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull RCTRemoteNotificationCallback)completionHandler {
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: userInfo];
[data setValue:@"remote_notification" forKey:@"_notificationType"];
......@@ -171,28 +176,13 @@ RCT_EXPORT_MODULE();
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)setBridge:(RCTBridge *)bridge
{
_bridge = bridge;
- (instancetype)init {
self = [super init];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleNotificationReceived:)
name:FCMNotificationReceived
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(disconnectFCM)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(connectToFCM)
name:UIApplicationDidBecomeActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(onTokenRefresh)
name:kFIRInstanceIDTokenRefreshNotification object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(sendDataMessageFailure:)
name:FIRMessagingSendErrorNotification object:nil];
......@@ -201,48 +191,49 @@ RCT_EXPORT_MODULE();
addObserver:self selector:@selector(sendDataMessageSuccess:)
name:FIRMessagingSendSuccessNotification object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(connectionStateChanged:)
name:FIRMessagingConnectionStateChangedNotification object:nil];
// For iOS 10 data message (sent via FCM)
dispatch_async(dispatch_get_main_queue(), ^{
[[FIRMessaging messaging] setRemoteMessageDelegate:self];
[self connectToFCM];
[[FIRMessaging messaging] setDelegate:self];
});
return self;
}
- (void)connectToFCM
RCT_EXPORT_METHOD(enableDirectChannel)
{
[[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(@"Unable to connect to FCM. %@", error);
} else {
NSLog(@"Connected to FCM.");
}
}];
[[FIRMessaging messaging] setShouldEstablishDirectChannel:@YES];
}
- (void)disconnectFCM
RCT_EXPORT_METHOD(isDirectChannelEstablished:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
[[FIRMessaging messaging] disconnect];
NSLog(@"Disconnected from FCM");
resolve([[FIRMessaging messaging] isDirectChannelEstablished] ? @YES: @NO);
}
RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve)
RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
UILocalNotification *localUserInfo = _bridge.launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
if (localUserInfo) {
resolve([[localUserInfo userInfo] copy]);
return;
}
} else {
resolve([_bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] copy]);
}
}
RCT_EXPORT_METHOD(getFCMToken:(RCTPromiseResolveBlock)resolve)
RCT_EXPORT_METHOD(getAPNSToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
resolve([[FIRInstanceID instanceID] token]);
resolve([FIRMessaging messaging].APNSToken);
}
- (void) onTokenRefresh
RCT_EXPORT_METHOD(getFCMToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
[self sendEventWithName:@"FCMTokenRefreshed" body:[[FIRInstanceID instanceID] token]];
resolve([FIRMessaging messaging].FCMToken);
}
- (void)messaging:(nonnull FIRMessaging *)messaging didRefreshRegistrationToken:(nonnull NSString *)fcmToken {
[self sendEventWithName:FCMTokenRefreshed body:fcmToken];
}
RCT_EXPORT_METHOD(requestPermissions:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
......@@ -373,7 +364,7 @@ RCT_EXPORT_METHOD(cancelLocalNotification:(NSString*) notificationId)
}
}
RCT_EXPORT_METHOD(getScheduledLocalNotifications:(RCTPromiseResolveBlock)resolve)
RCT_EXPORT_METHOD(getScheduledLocalNotifications:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
if([UNUserNotificationCenter currentNotificationCenter] != nil){
[[UNUserNotificationCenter currentNotificationCenter] getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
......@@ -398,7 +389,7 @@ RCT_EXPORT_METHOD(setBadgeNumber: (NSInteger*) number)
[RCTSharedApplication() setApplicationIconBadgeNumber:*number];
}
RCT_EXPORT_METHOD(getBadgeNumber: (RCTPromiseResolveBlock)resolve)
RCT_EXPORT_METHOD(getBadgeNumber: (RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
resolve(@([RCTSharedApplication() applicationIconBadgeNumber]));
}
......@@ -484,4 +475,10 @@ RCT_EXPORT_METHOD(finishNotificationResponse: (NSString *)completionHandlerId){
NSLog(@"sendDataMessageSuccess: %@", messageID);
}
- (void)connectionStateChanged:(NSNotification *)notification
{
[self sendEventWithName:FCMDirectChannelConnectionChanged body:[FIRMessaging messaging].isDirectChannelEstablished ? @YES: @NO];
NSLog(@"connectionStateChanged: %@", [FIRMessaging messaging].isDirectChannelEstablished ? @"connected": @"disconnected");
}
@end
......@@ -139,6 +139,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
......@@ -161,6 +162,7 @@
"-Wextra",
"-Wall",
"-Wno-semicolon-before-method-body",
"-Wno-unused-parameter",
);
};
name = Debug;
......@@ -183,6 +185,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
......@@ -203,6 +206,7 @@
"-Wextra",
"-Wall",
"-Wno-semicolon-before-method-body",
"-Wno-unused-parameter",
);
};
name = Release;
......
......@@ -7,7 +7,7 @@
<key>RNFIRMessaging.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>7</integer>
<integer>4</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment