Skip to content

Commit 566665e

Browse files
authored
Delete app from Database when deleted in Core. (#194)
* Delete an app from Database when deleted in Core. When a FIRApp is deleted in Core, it should also be deleted from the instances array in Database. See #160 for more details. * Add tests for deleting databases. * Add call to clean up deleted FIRDatabase instance.
1 parent 5547660 commit 566665e

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

Example/Database/Tests/Integration/FIRDatabaseTests.m

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,56 @@ - (void) testDatabaseForAppWithInvalidURLs {
5353
XCTAssertThrows([self databaseForURL:@"http://x.example.com/paths/are/bad"]);
5454
}
5555

56+
- (void) testDeleteDatabase {
57+
FIRDatabase *defaultDatabase = [FIRDatabase database];
58+
FIRApp *defaultApp = [FIRApp defaultApp];
59+
XCTAssertEqualObjects(defaultDatabase.app, defaultApp);
60+
61+
// Set up expectation for the default app to be deleted.
62+
XCTestExpectation *defaultAppDeletedExpectation =
63+
[self expectationWithDescription:@"Deleting the default app should invalidate the default "
64+
@"database."];
65+
[defaultApp deleteApp:^(BOOL success) {
66+
// Deleting the default app should make the default database unavailable.
67+
XCTAssertThrows([FIRDatabase database]);
68+
69+
[defaultAppDeletedExpectation fulfill];
70+
}];
71+
72+
// Wait for the default app to be deleted.
73+
[self waitForExpectations:@[defaultAppDeletedExpectation] timeout:2];
74+
75+
// Set up a custom FIRApp with a custom database based on it.
76+
FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:@"1:123:ios:123abc"
77+
GCMSenderID:@"gcm_sender_id"];
78+
options.databaseURL = self.databaseURL;
79+
NSString *customAppName = @"MyCustomApp";
80+
[FIRApp configureWithName:customAppName options:options];
81+
FIRApp *customApp = [FIRApp appNamed:customAppName];
82+
FIRDatabase *customDatabase = [FIRDatabase databaseForApp:customApp];
83+
XCTAssertNotNil(customDatabase);
84+
85+
// Delete the custom app and wait for it to be done.
86+
XCTestExpectation *customAppDeletedExpectation =
87+
[self expectationWithDescription:@"Deleting the custom app should be successful."];
88+
[customApp deleteApp:^(BOOL success) {
89+
// The app shouldn't exist anymore, ensure that the databaseForApp throws.
90+
XCTAssertThrows([FIRDatabase databaseForApp:[FIRApp appNamed:customAppName]]);
91+
92+
[customAppDeletedExpectation fulfill];
93+
}];
94+
95+
// Wait for the custom app to be deleted.
96+
[self waitForExpectations:@[customAppDeletedExpectation] timeout:2];
97+
98+
// Configure the app again, then grab a reference to the database. Assert it's different.
99+
[FIRApp configureWithName:customAppName options:options];
100+
FIRApp *secondCustomApp = [FIRApp appNamed:customAppName];
101+
FIRDatabase *secondCustomDatabase = [FIRDatabase databaseForApp:secondCustomApp];
102+
XCTAssertNotNil(secondCustomDatabase);
103+
XCTAssertNotEqualObjects(customDatabase, secondCustomDatabase);
104+
}
105+
56106
- (void) testReferenceWithPath {
57107
FIRDatabase *db = [self defaultDatabase];
58108
NSString *expectedURL = [NSString stringWithFormat:@"%@/foo", self.databaseURL];

Firebase/Database/Api/FIRDatabase.m

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,26 @@ @implementation FIRDatabase
4242
#define STR_EXPAND(x) #x
4343
static const char *FIREBASE_SEMVER = (const char *)STR(FIRDatabase_VERSION);
4444

45+
+ (void)load {
46+
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
47+
[center addObserverForName:kFIRAppDeleteNotification
48+
object:nil
49+
queue:nil
50+
usingBlock:^(NSNotification * _Nonnull note) {
51+
NSString *appName = note.userInfo[kFIRAppNameKey];
52+
if (appName == nil) { return; }
53+
54+
NSMutableDictionary *instances = [self instances];
55+
@synchronized (instances) {
56+
FIRDatabase *deletedApp = instances[appName];
57+
// Clean up the deleted instance in an effort to remove any resources still in use.
58+
// Note: Any leftover instances of this exact database will be invalid.
59+
[FRepoManager disposeRepos:deletedApp.config];
60+
[instances removeObjectForKey:appName];
61+
}
62+
}];
63+
}
64+
4565
/**
4666
* A static NSMutableDictionary of FirebaseApp names to FirebaseDatabase instance. To ensure thread-
4767
* safety, it should only be accessed in databaseForApp, which is synchronized.

0 commit comments

Comments
 (0)