Skip to content

Commit 615c20c

Browse files
authored
Ensure Messaging instance is usable after FIRApp's delete (#3579)
* Ensure Messaging instance is usable after FIRApp's `delete` This fixes #3411. Test fails before the code change, and succeeds afterwards. * Update CHANGELOG.md * Use Bug number instead of PR number
1 parent 9776ee5 commit 615c20c

File tree

5 files changed

+75
-12
lines changed

5 files changed

+75
-12
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2019 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import FirebaseCore
18+
import FirebaseMessaging
19+
import XCTest
20+
21+
class FIRMessagingInstanceTest: XCTestCase {
22+
23+
func testSingleton_worksAfterDelete() {
24+
// This is an example of a functional test case.
25+
// Use XCTAssert and related functions to verify your tests produce the correct results.
26+
let options = FirebaseOptions(googleAppID: "1:123:ios:123abc", gcmSenderID: "valid-sender-id")
27+
FirebaseApp.configure(options: options)
28+
let original = Messaging.messaging()
29+
30+
// Ensure the client is set up as expected.
31+
guard let isOrigClientSetup = original.value(forKey: "isClientSetup") as? Bool else {
32+
XCTFail("Could not get internal Messaging variable `isClientSetup`.")
33+
return
34+
}
35+
36+
XCTAssertTrue(isOrigClientSetup, "Property `isClientSetup` should be true after creation.")
37+
38+
// Get and delete the default app.
39+
guard let defaultApp = FirebaseApp.app() else {
40+
XCTFail("Default app was not configured properly.")
41+
return
42+
}
43+
44+
// The delete API is synchronous, so the default app will be deleted afterwards.
45+
defaultApp.delete { (success) in
46+
XCTAssertTrue(success, "FirebaseApp deletion should be successful")
47+
}
48+
49+
XCTAssertNil(FirebaseApp.app(), "The default app should be `nil` at this point.")
50+
51+
// Re-configure the app to trigger Messaging to re-instantiate.
52+
FirebaseApp.configure(options: options)
53+
54+
// Get another instance of Messaging, make sure it's not the same instance.
55+
let postDelete = Messaging.messaging()
56+
XCTAssertNotEqual(original, postDelete)
57+
58+
// Ensure the new client is set up as expected.
59+
guard let isClientSetup = postDelete.value(forKey: "isClientSetup") as? Bool else {
60+
XCTFail("Could not get internal Messaging variable `isClientSetup`.")
61+
return
62+
}
63+
64+
XCTAssertTrue(isClientSetup, "Property `isClientSetup` should be true after creation.")
65+
}
66+
}

Example/Messaging/Tests/FIRMessagingTest.m

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ - (void)setUp {
6161
NSUserDefaults *defaults =
6262
[[NSUserDefaults alloc] initWithSuiteName:kFIRMessagingDefaultsTestDomain];
6363
_messaging = [FIRMessagingTestUtilities messagingForTestsWithUserDefaults:defaults];
64-
6564
_mockFirebaseApp = OCMClassMock([FIRApp class]);
6665
OCMStub([_mockFirebaseApp defaultApp]).andReturn(_mockFirebaseApp);
6766
_mockInstanceID = OCMPartialMock(self.messaging.instanceID);

Firebase/Messaging/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# 2019-08-20 -- v4.1.3
22
- [changed] Cleaned up the documents, unused macros, and folders. (#3490, #3537, #3556, #3498)
33
- [changed] Updated the header path to pod repo relative. (#3527)
4+
- [fixed] Fix singleton functionality after a FirebaseApp is deleted and recreated. (#3411)
45

56
# 2019-08-08 -- v4.1.2
67
- [fixed] Fix hang when token is not available before topic subscription and unsubscription. (#3438)

Firebase/Messaging/FIRMessaging.m

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,7 @@ + (FIRMessaging *)messaging {
167167
FIR_COMPONENT(FIRMessagingInstanceProvider, defaultApp.container);
168168

169169
// We know the instance coming from the container is a FIRMessaging instance, cast it and move on.
170-
FIRMessaging *messaging = (FIRMessaging *)instance;
171-
172-
static dispatch_once_t onceToken;
173-
dispatch_once(&onceToken, ^{
174-
[messaging start];
175-
});
176-
return messaging;
170+
return (FIRMessaging *)instance;
177171
}
178172

179173
+ (FIRMessagingExtensionHelper *)extensionHelper {
@@ -220,9 +214,12 @@ + (void)load {
220214
// Ensure it's cached so it returns the same instance every time messaging is called.
221215
*isCacheable = YES;
222216
id<FIRAnalyticsInterop> analytics = FIR_COMPONENT(FIRAnalyticsInterop, container);
223-
return [[FIRMessaging alloc] initWithAnalytics:analytics
224-
withInstanceID:[FIRInstanceID instanceID]
225-
withUserDefaults:[GULUserDefaults standardUserDefaults]];
217+
FIRMessaging *messaging =
218+
[[FIRMessaging alloc] initWithAnalytics:analytics
219+
withInstanceID:[FIRInstanceID instanceID]
220+
withUserDefaults:[GULUserDefaults standardUserDefaults]];
221+
[messaging start];
222+
return messaging;
226223
};
227224
FIRComponent *messagingProvider =
228225
[FIRComponent componentWithProtocol:@protocol(FIRMessagingInstanceProvider)

FirebaseMessaging.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ device, and it is completely free.
5252
s.dependency 'Protobuf', '~> 3.1'
5353

5454
s.test_spec 'unit' do |unit_tests|
55-
unit_tests.source_files = 'Example/Messaging/Tests/*.[mh]'
55+
unit_tests.source_files = 'Example/Messaging/Tests/*.{m,h,swift}'
5656
unit_tests.requires_app_host = true
5757
unit_tests.pod_target_xcconfig = {
5858
'CLANG_ENABLE_OBJC_WEAK' => 'YES'

0 commit comments

Comments
 (0)