Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(messaging, ios): prevent getInitialMessage from being null at the start of the app #9969

Merged
merged 3 commits into from Nov 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -9,14 +9,14 @@ import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:http/http.dart' as http;

import 'firebase_options.dart';
import 'message.dart';
import 'message_list.dart';
import 'permissions.dart';
import 'token_monitor.dart';
import 'firebase_options.dart';

/// Working example of FirebaseMessaging.
/// Please use this in order to verify messages are working in foreground, background & terminated state.
Expand Down Expand Up @@ -171,11 +171,22 @@ class Application extends StatefulWidget {

class _Application extends State<Application> {
String? _token;
String? initialMessage;
bool _resolved = false;

@override
void initState() {
super.initState();

FirebaseMessaging.instance.getInitialMessage().then(
(value) => setState(
() {
_resolved = true;
initialMessage = value?.data.toString();
},
),
);

FirebaseMessaging.onMessage.listen(showFlutterNotification);

FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
Expand Down Expand Up @@ -289,13 +300,25 @@ class _Application extends State<Application> {
child: Column(
children: [
MetaCard('Permissions', Permissions()),
MetaCard(
'Initial Message',
Column(
children: [
Text(_resolved ? 'Resolved' : 'Resolving'),
Text(initialMessage ?? 'None'),
],
),
),
MetaCard(
'FCM Token',
TokenMonitor((token) {
_token = token;
return token == null
? const CircularProgressIndicator()
: Text(token, style: const TextStyle(fontSize: 12));
: SelectableText(
token,
style: const TextStyle(fontSize: 12),
);
}),
),
ElevatedButton(
Expand Down
Expand Up @@ -22,6 +22,12 @@ @implementation FLTFirebaseMessagingPlugin {
NSObject<FlutterPluginRegistrar> *_registrar;
NSData *_apnsToken;
NSDictionary *_initialNotification;

// Used to track if everything as been initialized before answering
// to the initialNotification request
BOOL _initialNotificationGathered;
FLTFirebaseMethodCallResult *_initialNotificationResult;

NSString *_initialNoticationID;
NSString *_notificationOpenedAppID;

Expand All @@ -43,6 +49,7 @@ - (instancetype)initWithFlutterMethodChannel:(FlutterMethodChannel *)channel
andFlutterPluginRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
self = [super init];
if (self) {
_initialNotificationGathered = NO;
_channel = channel;
_registrar = registrar;
// Application
Expand Down Expand Up @@ -109,7 +116,9 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)flutter
[self ensureAPNSTokenSetting];

if ([@"Messaging#getInitialMessage" isEqualToString:call.method]) {
methodCallResult.success([self copyInitialNotification]);
_initialNotificationResult = methodCallResult;
[self initialNotificationCallback];

} else if ([@"Messaging#deleteToken" isEqualToString:call.method]) {
[self messagingDeleteToken:call.arguments withMethodCallResult:methodCallResult];
} else if ([@"Messaging#getAPNSToken" isEqualToString:call.method]) {
Expand Down Expand Up @@ -207,6 +216,8 @@ - (void)application_onDidFinishLaunchingNotification:(nonnull NSNotification *)n
[FLTFirebaseMessagingPlugin remoteMessageUserInfoToDict:remoteNotification];
_initialNoticationID = remoteNotification[@"gcm.message_id"];
}
_initialNotificationGathered = YES;
[self initialNotificationCallback];

#if TARGET_OS_OSX
// For macOS we use swizzling to intercept as addApplicationDelegate does not exist on the macOS
Expand Down Expand Up @@ -330,7 +341,7 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center
}
}

// Called when a use interacts with a notification.
// Called when a user interacts with a notification.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
Expand Down Expand Up @@ -1013,6 +1024,13 @@ - (nullable NSDictionary *)copyInitialNotification {
return nil;
}

- (void)initialNotificationCallback {
if (_initialNotificationGathered && _initialNotificationResult != nil) {
_initialNotificationResult.success([self copyInitialNotification]);
_initialNotificationResult = nil;
}
}

- (NSDictionary *)NSDictionaryForNSError:(NSError *)error {
NSString *code = @"unknown";
NSString *message = @"An unknown error has occurred.";
Expand Down