Skip to content

Commit c049f74

Browse files
fix an issue that delete token does not trigger token refresh notification or delegate (#5339)
1 parent 77394a4 commit c049f74

File tree

11 files changed

+147
-72
lines changed

11 files changed

+147
-72
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1120"
4+
version = "1.3">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
<BuildActionEntries>
9+
<BuildActionEntry
10+
buildForTesting = "YES"
11+
buildForRunning = "YES"
12+
buildForProfiling = "YES"
13+
buildForArchiving = "YES"
14+
buildForAnalyzing = "YES">
15+
<BuildableReference
16+
BuildableIdentifier = "primary"
17+
BlueprintIdentifier = "5125CC982437F471006CA5D0"
18+
BuildableName = "Sample.app"
19+
BlueprintName = "Sample"
20+
ReferencedContainer = "container:Sample.xcodeproj">
21+
</BuildableReference>
22+
</BuildActionEntry>
23+
</BuildActionEntries>
24+
</BuildAction>
25+
<TestAction
26+
buildConfiguration = "Debug"
27+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
shouldUseLaunchSchemeArgsEnv = "YES">
30+
<Testables>
31+
</Testables>
32+
</TestAction>
33+
<LaunchAction
34+
buildConfiguration = "Debug"
35+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
36+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
37+
launchStyle = "0"
38+
useCustomWorkingDirectory = "NO"
39+
ignoresPersistentStateOnLaunch = "NO"
40+
debugDocumentVersioning = "YES"
41+
debugServiceExtension = "internal"
42+
allowLocationSimulation = "YES">
43+
<BuildableProductRunnable
44+
runnableDebuggingMode = "0">
45+
<BuildableReference
46+
BuildableIdentifier = "primary"
47+
BlueprintIdentifier = "5125CC982437F471006CA5D0"
48+
BuildableName = "Sample.app"
49+
BlueprintName = "Sample"
50+
ReferencedContainer = "container:Sample.xcodeproj">
51+
</BuildableReference>
52+
</BuildableProductRunnable>
53+
<CommandLineArguments>
54+
<CommandLineArgument
55+
argument = "-FIRDebugEnabled"
56+
isEnabled = "YES">
57+
</CommandLineArgument>
58+
</CommandLineArguments>
59+
</LaunchAction>
60+
<ProfileAction
61+
buildConfiguration = "Release"
62+
shouldUseLaunchSchemeArgsEnv = "YES"
63+
savedToolIdentifier = ""
64+
useCustomWorkingDirectory = "NO"
65+
debugDocumentVersioning = "YES">
66+
<BuildableProductRunnable
67+
runnableDebuggingMode = "0">
68+
<BuildableReference
69+
BuildableIdentifier = "primary"
70+
BlueprintIdentifier = "5125CC982437F471006CA5D0"
71+
BuildableName = "Sample.app"
72+
BlueprintName = "Sample"
73+
ReferencedContainer = "container:Sample.xcodeproj">
74+
</BuildableReference>
75+
</BuildableProductRunnable>
76+
</ProfileAction>
77+
<AnalyzeAction
78+
buildConfiguration = "Debug">
79+
</AnalyzeAction>
80+
<ArchiveAction
81+
buildConfiguration = "Release"
82+
revealArchiveInOrganizer = "YES">
83+
</ArchiveAction>
84+
</Scheme>

Example/Messaging/Sample/Sample/AppDelegate.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313
// limitations under the License.
1414

1515
import UIKit
16-
import CoreData
1716
import FirebaseCore
18-
import FirebaseMessaging
1917

2018
@UIApplicationMain
2119
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

Example/Messaging/Sample/Sample/ContentView.swift

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
import Combine
1516
import SwiftUI
1617
import FirebaseCore
1718
import FirebaseMessaging
@@ -109,7 +110,6 @@ struct ContentView: View {
109110
print("Failed delete token: ", error)
110111
return
111112
}
112-
self.identity.token = nil
113113
}
114114
}
115115

@@ -119,8 +119,6 @@ struct ContentView: View {
119119
print("Failed delete ID: ", error)
120120
return
121121
}
122-
self.identity.instanceID = nil
123-
self.identity.token = nil
124122
}
125123
}
126124

@@ -130,7 +128,6 @@ struct ContentView: View {
130128
print("Failed delete FID: ", error)
131129
return
132130
}
133-
self.identity.instanceID = nil
134131
}
135132
}
136133
}
@@ -162,8 +159,6 @@ struct ContentView_Previews: PreviewProvider {
162159

163160
static var previews: some View {
164161
Group {
165-
ContentView().environmentObject(Identity())
166-
167162
ContentView().environmentObject(filledIdentity)
168163
}
169164
}

Example/Messaging/Sample/Sample/Identity.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,22 @@
1313
// limitations under the License.
1414

1515
import SwiftUI
16+
import FirebaseMessaging
17+
import FirebaseInstallations
1618

1719
public final class Identity: ObservableObject {
1820
// Identity that is unique per app.
1921
@Published public var instanceID: String? = nil
2022
// The token that Firebase Messaging use to send notifications.
2123
@Published public var token: String? = nil
24+
25+
init() {
26+
Installations.installations().installationID(completion: { fid, error in
27+
if let error = error as NSError? {
28+
print("Failed to get FID: ", error)
29+
return
30+
}
31+
self.instanceID = fid ?? "None"
32+
})
33+
}
2234
}

Example/Messaging/Sample/Sample/SceneDelegate.swift

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, MessagingDelegate {
2626
options connectionOptions: UIScene.ConnectionOptions) {
2727
let contentView = ContentView()
2828
// Use a UIHostingController as window root view controller.
29-
Messaging.messaging().delegate = self
3029
if let windowScene = scene as? UIWindowScene {
3130
let window = UIWindow(windowScene: windowScene)
3231
window
@@ -35,12 +34,27 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, MessagingDelegate {
3534
self.window = window
3635
window.makeKeyAndVisible()
3736
}
38-
}
3937

40-
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
41-
identity.token = fcmToken
42-
InstanceID.instanceID().instanceID { result, error in
43-
self.identity.instanceID = result?.instanceID
44-
}
38+
// Subscribe to token refresh
39+
_ = NotificationCenter.default
40+
.publisher(for: Notification.Name.MessagingRegistrationTokenRefreshed)
41+
.map { $0.object as? String }
42+
.receive(on: RunLoop.main)
43+
.assign(to: \Identity.token, on: identity)
44+
45+
// Subscribe to fid changes
46+
_ = NotificationCenter.default
47+
.publisher(for: Notification.Name.FIRInstallationIDDidChange)
48+
.map { _ in }
49+
.receive(on: RunLoop.main)
50+
.sink(receiveValue: {
51+
Installations.installations().installationID(completion: { fid, error in
52+
if let error = error as NSError? {
53+
print("Failed to get FID: ", error)
54+
return
55+
}
56+
self.identity.instanceID = fid ?? "None"
57+
})
58+
})
4559
}
4660
}

Firebase/InstanceID/FIRInstanceID.m

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -245,19 +245,20 @@ - (NSString *)cachedTokenIfAvailable {
245245
}
246246

247247
- (void)setDefaultFCMToken:(NSString *)defaultFCMToken {
248-
if (_defaultFCMToken && defaultFCMToken && [defaultFCMToken isEqualToString:_defaultFCMToken]) {
249-
return;
248+
// Sending this notification out will ensure that FIRMessaging and FIRInstanceID has the updated
249+
// default FCM token.
250+
// Only notify of token refresh if we have a new valid token that's different than before
251+
if ((defaultFCMToken.length && _defaultFCMToken.length &&
252+
![defaultFCMToken isEqualToString:_defaultFCMToken]) ||
253+
defaultFCMToken.length != _defaultFCMToken.length) {
254+
NSNotification *tokenRefreshNotification =
255+
[NSNotification notificationWithName:kFIRInstanceIDTokenRefreshNotification
256+
object:[defaultFCMToken copy]];
257+
[[NSNotificationQueue defaultQueue] enqueueNotification:tokenRefreshNotification
258+
postingStyle:NSPostASAP];
250259
}
251260

252261
_defaultFCMToken = defaultFCMToken;
253-
254-
// Sending this notification out will ensure that FIRMessaging has the updated
255-
// default FCM token.
256-
NSNotification *internalDefaultTokenNotification =
257-
[NSNotification notificationWithName:kFIRInstanceIDDefaultGCMTokenNotification
258-
object:_defaultFCMToken];
259-
[[NSNotificationQueue defaultQueue] enqueueNotification:internalDefaultTokenNotification
260-
postingStyle:NSPostASAP];
261262
}
262263

263264
- (void)tokenWithAuthorizedEntity:(NSString *)authorizedEntity
@@ -837,18 +838,10 @@ - (void)defaultTokenWithRetry:(BOOL)retry handler:(nullable FIRInstanceIDTokenHa
837838
// Post the required notifications if somebody is waiting.
838839
FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeInstanceID008, @"Got default token %@",
839840
token);
840-
NSString *previousFCMToken = self.defaultFCMToken;
841+
// Update default FCM token, this method also triggers sending notification if token has
842+
// changed.
841843
self.defaultFCMToken = token;
842844

843-
// Only notify of token refresh if we have a new valid token that's different than before
844-
if (self.defaultFCMToken.length && ![self.defaultFCMToken isEqualToString:previousFCMToken]) {
845-
NSNotification *tokenRefreshNotification =
846-
[NSNotification notificationWithName:kFIRInstanceIDTokenRefreshNotification
847-
object:[self.defaultFCMToken copy]];
848-
[[NSNotificationQueue defaultQueue] enqueueNotification:tokenRefreshNotification
849-
postingStyle:NSPostASAP];
850-
}
851-
852845
[self performDefaultTokenHandlerWithToken:token error:nil];
853846
}
854847
};

Firebase/InstanceID/FIRInstanceIDConstants.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ FOUNDATION_EXPORT NSString *const kFIRInstanceID_CMD_RST;
2929
/// Notification used to deliver GCM messages for InstanceID.
3030
FOUNDATION_EXPORT NSString *const kFIRInstanceIDCheckinFetchedNotification;
3131
FOUNDATION_EXPORT NSString *const kFIRInstanceIDAPNSTokenNotification;
32-
FOUNDATION_EXPORT NSString *const kFIRInstanceIDDefaultGCMTokenNotification;
3332
FOUNDATION_EXPORT NSString *const kFIRInstanceIDDefaultGCMTokenFailNotification;
3433

3534
FOUNDATION_EXPORT NSString *const kFIRInstanceIDIdentityInvalidatedNotification;

Firebase/InstanceID/FIRInstanceIDConstants.m

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
// NOTIFICATIONS
2323
NSString *const kFIRInstanceIDCheckinFetchedNotification = @"com.google.gcm.notif-checkin-fetched";
2424
NSString *const kFIRInstanceIDAPNSTokenNotification = @"com.firebase.iid.notif.apns-token";
25-
NSString *const kFIRInstanceIDDefaultGCMTokenNotification = @"com.firebase.iid.notif.fcm-token";
2625
NSString *const kFIRInstanceIDDefaultGCMTokenFailNotification =
2726
@"com.firebase.iid.notif.fcm-token-fail";
2827

Firebase/Messaging/FIRMessaging.m

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -307,11 +307,6 @@ - (void)setupNotificationListeners {
307307
// To prevent multiple notifications remove self as observer for all events.
308308
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
309309
[center removeObserver:self];
310-
311-
[center addObserver:self
312-
selector:@selector(didReceiveDefaultInstanceIDToken:)
313-
name:kFIRMessagingFCMTokenNotification
314-
object:nil];
315310
[center addObserver:self
316311
selector:@selector(defaultInstanceIDTokenWasRefreshed:)
317312
name:kFIRMessagingRegistrationTokenRefreshNotification
@@ -664,6 +659,10 @@ - (void)notifyDelegateOfFCMTokenAvailability {
664659
if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) {
665660
[self.delegate messaging:self didReceiveRegistrationToken:self.defaultFcmToken];
666661
}
662+
// Should always trigger the token refresh notification when the delegate method is called
663+
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
664+
[center postNotificationName:FIRMessagingRegistrationTokenRefreshedNotification
665+
object:self.defaultFcmToken];
667666
}
668667

669668
#pragma mark - Application State Changes
@@ -931,41 +930,29 @@ - (FIRMessagingNetworkStatus)networkType {
931930

932931
#pragma mark - Notifications
933932

934-
- (void)didReceiveDefaultInstanceIDToken:(NSNotification *)notification {
933+
- (void)defaultInstanceIDTokenWasRefreshed:(NSNotification *)notification {
935934
if (notification.object && ![notification.object isKindOfClass:[NSString class]]) {
936935
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging015,
937936
@"Invalid default FCM token type %@",
938937
NSStringFromClass([notification.object class]));
939938
return;
940939
}
940+
// Retrieve the Instance ID default token, and should notify delegate and
941+
// trigger notification as long as the token is different from previous state.
941942
NSString *oldToken = self.defaultFcmToken;
942-
self.defaultFcmToken = [(NSString *)notification.object copy];
943-
if (self.defaultFcmToken && ![self.defaultFcmToken isEqualToString:oldToken]) {
943+
NSString *token = [(NSString *)notification.object copy];
944+
self.defaultFcmToken = [token copy];
945+
if ((self.defaultFcmToken.length && oldToken.length &&
946+
![self.defaultFcmToken isEqualToString:oldToken]) ||
947+
self.defaultFcmToken.length != oldToken.length) {
944948
[self notifyDelegateOfFCMTokenAvailability];
945-
}
946-
[self.pubsub scheduleSync:YES];
949+
[self.pubsub scheduleSync:YES];
947950
#pragma clang diagnostic push
948951
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
949-
if (self.shouldEstablishDirectChannel) {
950-
[self updateAutomaticClientConnection];
951-
}
952-
#pragma clang diagnostic pop
953-
}
954-
955-
- (void)defaultInstanceIDTokenWasRefreshed:(NSNotification *)notification {
956-
// Retrieve the Instance ID default token, and if it is non-nil, post it
957-
NSString *token = self.instanceID.token;
958-
// Sometimes Instance ID doesn't yet have a token, so wait until the default
959-
// token is fetched, and then notify. This ensures that this token should not
960-
// be nil when the developer accesses it.
961-
if (token != nil) {
962-
NSString *oldToken = self.defaultFcmToken;
963-
self.defaultFcmToken = [token copy];
964-
if (self.defaultFcmToken && ![self.defaultFcmToken isEqualToString:oldToken]) {
965-
[self notifyDelegateOfFCMTokenAvailability];
952+
if (self.shouldEstablishDirectChannel) {
953+
[self updateAutomaticClientConnection];
966954
}
967-
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
968-
[center postNotificationName:FIRMessagingRegistrationTokenRefreshedNotification object:nil];
955+
#pragma clang diagnostic pop
969956
}
970957
}
971958

Firebase/Messaging/FIRMessagingConstants.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@ FOUNDATION_EXPORT NSString *const kFIRMessagingSubDirectoryName;
4949
// Notifications
5050
FOUNDATION_EXPORT NSString *const kFIRMessagingCheckinFetchedNotification;
5151
FOUNDATION_EXPORT NSString *const kFIRMessagingAPNSTokenNotification;
52-
FOUNDATION_EXPORT NSString *const kFIRMessagingFCMTokenNotification;
53-
FOUNDATION_EXPORT NSString *const kFIRMessagingInstanceIDTokenRefreshNotification
54-
__deprecated_msg("Use kFIRMessagingRegistrationTokenRefreshNotification instead");
5552
FOUNDATION_EXPORT NSString *const kFIRMessagingRegistrationTokenRefreshNotification;
5653

5754
FOUNDATION_EXPORT const int kFIRMessagingSendTtlDefault; // 24 hours

0 commit comments

Comments
 (0)