Skip to content

Delete app from Database when deleted in Core. #194

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

Merged
merged 3 commits into from
Aug 17, 2017
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions Example/Database/Tests/Integration/FIRDatabaseTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,56 @@ - (void) testDatabaseForAppWithInvalidURLs {
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];
Expand Down
20 changes: 20 additions & 0 deletions Firebase/Database/Api/FIRDatabase.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@ @implementation FIRDatabase
#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.
Expand Down