aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Example/Database/Tests/Integration/FIRDatabaseTests.m50
-rw-r--r--Firebase/Database/Api/FIRDatabase.m20
2 files changed, 70 insertions, 0 deletions
diff --git a/Example/Database/Tests/Integration/FIRDatabaseTests.m b/Example/Database/Tests/Integration/FIRDatabaseTests.m
index 3b20a46..4bdb773 100644
--- a/Example/Database/Tests/Integration/FIRDatabaseTests.m
+++ b/Example/Database/Tests/Integration/FIRDatabaseTests.m
@@ -53,6 +53,56 @@ static const NSInteger kFErrorCodeWriteCanceled = 3;
XCTAssertThrows([self databaseForURL:@"http://x.example.com/paths/are/bad"]);
}
+- (void) testDeleteDatabase {
+ FIRDatabase *defaultDatabase = [FIRDatabase database];
+ FIRApp *defaultApp = [FIRApp defaultApp];
+ XCTAssertEqualObjects(defaultDatabase.app, defaultApp);
+
+ // Set up expectation for the default app to be deleted.
+ XCTestExpectation *defaultAppDeletedExpectation =
+ [self expectationWithDescription:@"Deleting the default app should invalidate the default "
+ @"database."];
+ [defaultApp deleteApp:^(BOOL success) {
+ // Deleting the default app should make the default database unavailable.
+ XCTAssertThrows([FIRDatabase database]);
+
+ [defaultAppDeletedExpectation fulfill];
+ }];
+
+ // Wait for the default app to be deleted.
+ [self waitForExpectations:@[defaultAppDeletedExpectation] timeout:2];
+
+ // Set up a custom FIRApp with a custom database based on it.
+ FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:@"1:123:ios:123abc"
+ GCMSenderID:@"gcm_sender_id"];
+ options.databaseURL = self.databaseURL;
+ NSString *customAppName = @"MyCustomApp";
+ [FIRApp configureWithName:customAppName options:options];
+ FIRApp *customApp = [FIRApp appNamed:customAppName];
+ FIRDatabase *customDatabase = [FIRDatabase databaseForApp:customApp];
+ XCTAssertNotNil(customDatabase);
+
+ // Delete the custom app and wait for it to be done.
+ XCTestExpectation *customAppDeletedExpectation =
+ [self expectationWithDescription:@"Deleting the custom app should be successful."];
+ [customApp deleteApp:^(BOOL success) {
+ // The app shouldn't exist anymore, ensure that the databaseForApp throws.
+ XCTAssertThrows([FIRDatabase databaseForApp:[FIRApp appNamed:customAppName]]);
+
+ [customAppDeletedExpectation fulfill];
+ }];
+
+ // Wait for the custom app to be deleted.
+ [self waitForExpectations:@[customAppDeletedExpectation] timeout:2];
+
+ // Configure the app again, then grab a reference to the database. Assert it's different.
+ [FIRApp configureWithName:customAppName options:options];
+ FIRApp *secondCustomApp = [FIRApp appNamed:customAppName];
+ FIRDatabase *secondCustomDatabase = [FIRDatabase databaseForApp:secondCustomApp];
+ XCTAssertNotNil(secondCustomDatabase);
+ XCTAssertNotEqualObjects(customDatabase, secondCustomDatabase);
+}
+
- (void) testReferenceWithPath {
FIRDatabase *db = [self defaultDatabase];
NSString *expectedURL = [NSString stringWithFormat:@"%@/foo", self.databaseURL];
diff --git a/Firebase/Database/Api/FIRDatabase.m b/Firebase/Database/Api/FIRDatabase.m
index 38ccd54..6ee163f 100644
--- a/Firebase/Database/Api/FIRDatabase.m
+++ b/Firebase/Database/Api/FIRDatabase.m
@@ -42,6 +42,26 @@
#define STR_EXPAND(x) #x
static const char *FIREBASE_SEMVER = (const char *)STR(FIRDatabase_VERSION);
++ (void)load {
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ [center addObserverForName:kFIRAppDeleteNotification
+ object:nil
+ queue:nil
+ usingBlock:^(NSNotification * _Nonnull note) {
+ NSString *appName = note.userInfo[kFIRAppNameKey];
+ if (appName == nil) { return; }
+
+ NSMutableDictionary *instances = [self instances];
+ @synchronized (instances) {
+ FIRDatabase *deletedApp = instances[appName];
+ // Clean up the deleted instance in an effort to remove any resources still in use.
+ // Note: Any leftover instances of this exact database will be invalid.
+ [FRepoManager disposeRepos:deletedApp.config];
+ [instances removeObjectForKey:appName];
+ }
+ }];
+}
+
/**
* A static NSMutableDictionary of FirebaseApp names to FirebaseDatabase instance. To ensure thread-
* safety, it should only be accessed in databaseForApp, which is synchronized.