This repository has been archived by the owner on Feb 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
/
FirebaseMessagingPlugin.m
194 lines (173 loc) · 7.47 KB
/
FirebaseMessagingPlugin.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "FirebaseMessagingPlugin.h"
#import "Firebase/Firebase.h"
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
@interface FLTFirebaseMessagingPlugin () <FIRMessagingDelegate>
@end
#endif
@implementation FLTFirebaseMessagingPlugin {
FlutterMethodChannel *_channel;
NSDictionary *_launchNotification;
BOOL _resumingFromBackground;
}
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
FlutterMethodChannel *channel =
[FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/firebase_messaging"
binaryMessenger:[registrar messenger]];
FLTFirebaseMessagingPlugin *instance =
[[FLTFirebaseMessagingPlugin alloc] initWithChannel:channel];
[registrar addApplicationDelegate:instance];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (instancetype)initWithChannel:(FlutterMethodChannel *)channel {
self = [super init];
if (self) {
_channel = channel;
_resumingFromBackground = NO;
if (![FIRApp appNamed:@"__FIRAPP_DEFAULT"]) {
NSLog(@"Configuring the default Firebase app...");
[FIRApp configure];
NSLog(@"Configured the default Firebase app %@.", [FIRApp defaultApp].name);
}
[FIRMessaging messaging].delegate = self;
}
return self;
}
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
NSString *method = call.method;
if ([@"requestNotificationPermissions" isEqualToString:method]) {
UIUserNotificationType notificationTypes = 0;
NSDictionary *arguments = call.arguments;
if ([arguments[@"sound"] boolValue]) {
notificationTypes |= UIUserNotificationTypeSound;
}
if ([arguments[@"alert"] boolValue]) {
notificationTypes |= UIUserNotificationTypeAlert;
}
if ([arguments[@"badge"] boolValue]) {
notificationTypes |= UIUserNotificationTypeBadge;
}
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
result(nil);
} else if ([@"configure" isEqualToString:method]) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
if (_launchNotification != nil) {
[_channel invokeMethod:@"onLaunch" arguments:_launchNotification];
}
result(nil);
} else if ([@"subscribeToTopic" isEqualToString:method]) {
NSString *topic = call.arguments;
[[FIRMessaging messaging] subscribeToTopic:topic];
result(nil);
} else if ([@"unsubscribeFromTopic" isEqualToString:method]) {
NSString *topic = call.arguments;
[[FIRMessaging messaging] unsubscribeFromTopic:topic];
result(nil);
} else if ([@"getToken" isEqualToString:method]) {
[[FIRInstanceID instanceID]
instanceIDWithHandler:^(FIRInstanceIDResult *_Nullable instanceIDResult,
NSError *_Nullable error) {
if (error != nil) {
NSLog(@"getToken, error fetching instanceID: %@", error);
result(nil);
} else {
result(instanceIDResult.token);
}
}];
} else if ([@"deleteInstanceID" isEqualToString:method]) {
[[FIRInstanceID instanceID] deleteIDWithHandler:^void(NSError *_Nullable error) {
if (error.code != 0) {
NSLog(@"deleteInstanceID, error: %@", error);
result([NSNumber numberWithBool:NO]);
} else {
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
result([NSNumber numberWithBool:YES]);
}
}];
} else if ([@"autoInitEnabled" isEqualToString:method]) {
BOOL *value = [[FIRMessaging messaging] isAutoInitEnabled];
result([NSNumber numberWithBool:value]);
} else if ([@"setAutoInitEnabled" isEqualToString:method]) {
NSNumber *value = call.arguments;
[FIRMessaging messaging].autoInitEnabled = value.boolValue;
result(nil);
} else {
result(FlutterMethodNotImplemented);
}
}
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
// Receive data message on iOS 10 devices while app is in the foreground.
- (void)applicationReceivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage {
[self didReceiveRemoteNotification:remoteMessage.appData];
}
#endif
- (void)didReceiveRemoteNotification:(NSDictionary *)userInfo {
if (_resumingFromBackground) {
[_channel invokeMethod:@"onResume" arguments:userInfo];
} else {
[_channel invokeMethod:@"onMessage" arguments:userInfo];
}
}
#pragma mark - AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (launchOptions != nil) {
_launchNotification = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
}
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
_resumingFromBackground = YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
_resumingFromBackground = NO;
// Clears push notifications from the notification center, with the
// side effect of resetting the badge count. We need to clear notifications
// because otherwise the user could tap notifications in the notification
// center while the app is in the foreground, and we wouldn't be able to
// distinguish that case from the case where a message came in and the
// user dismissed the notification center without tapping anything.
// TODO(goderbauer): Revisit this behavior once we provide an API for managing
// the badge number, or if we add support for running Dart in the background.
// Setting badgeNumber to 0 is a no-op (= notifications will not be cleared)
// if it is already 0,
// therefore the next line is setting it to 1 first before clearing it again
// to remove all
// notifications.
application.applicationIconBadgeNumber = 1;
application.applicationIconBadgeNumber = 0;
}
- (bool)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
[self didReceiveRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNoData);
return YES;
}
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
#ifdef DEBUG
[[FIRMessaging messaging] setAPNSToken:deviceToken type:FIRMessagingAPNSTokenTypeSandbox];
#else
[[FIRMessaging messaging] setAPNSToken:deviceToken type:FIRMessagingAPNSTokenTypeProd];
#endif
[_channel invokeMethod:@"onToken" arguments:[[FIRInstanceID instanceID] token]];
}
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
NSDictionary *settingsDictionary = @{
@"sound" : [NSNumber numberWithBool:notificationSettings.types & UIUserNotificationTypeSound],
@"badge" : [NSNumber numberWithBool:notificationSettings.types & UIUserNotificationTypeBadge],
@"alert" : [NSNumber numberWithBool:notificationSettings.types & UIUserNotificationTypeAlert],
};
[_channel invokeMethod:@"onIosSettingsRegistered" arguments:settingsDictionary];
}
- (void)messaging:(nonnull FIRMessaging *)messaging
didReceiveRegistrationToken:(nonnull NSString *)fcmToken {
[_channel invokeMethod:@"onToken" arguments:fcmToken];
}
@end