-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[FCM] Fix app launch crash #15559
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
[FCM] Fix app launch crash #15559
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -493,53 +493,62 @@ - (void)openDatabase { | |
| dispatch_async(_databaseOperationQueue, ^{ | ||
| NSFileManager *fileManager = [NSFileManager defaultManager]; | ||
| NSString *path = [self pathForDatabase]; | ||
|
|
||
| BOOL didOpenDatabase = YES; | ||
| if (![fileManager fileExistsAtPath:path]) { | ||
| // We've to separate between different versions here because of backward compatibility issues. | ||
| int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; | ||
| BOOL fileExists = [fileManager fileExistsAtPath:path]; | ||
|
|
||
| // Ensure the directory exists before trying to create the database if the file doesn't exist. | ||
| if (!fileExists) { | ||
| NSString *directory = [path stringByDeletingLastPathComponent]; | ||
| if (![fileManager fileExistsAtPath:directory]) { | ||
| NSError *error; | ||
| if (![fileManager createDirectoryAtPath:directory | ||
| withIntermediateDirectories:YES | ||
| attributes:nil | ||
| error:&error]) { | ||
| NSString *errorMessage = [NSString | ||
| stringWithFormat:@"Could not create RMQ database directory at path %@, error: %@", | ||
| directory, error]; | ||
| FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingDatabase, | ||
| @"%@", errorMessage); | ||
| NSAssert(NO, errorMessage); | ||
| return; | ||
| } | ||
| } | ||
| } | ||
| int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; | ||
| #ifdef SQLITE_OPEN_FILEPROTECTION_NONE | ||
| flags |= SQLITE_OPEN_FILEPROTECTION_NONE; | ||
| flags |= SQLITE_OPEN_FILEPROTECTION_NONE; | ||
| #endif | ||
| int result = sqlite3_open_v2([path UTF8String], &self -> _database, flags, NULL); | ||
| if (result != SQLITE_OK) { | ||
| NSString *errorString = FIRMessagingStringFromSQLiteResult(result); | ||
| NSString *errorMessage = [NSString | ||
| stringWithFormat:@"Could not open existing RMQ database at path %@, error: %@", path, | ||
| errorString]; | ||
| FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase, | ||
| @"%@", errorMessage); | ||
| NSAssert(NO, errorMessage); | ||
| return; | ||
| int result = sqlite3_open_v2([path UTF8String], &self -> _database, flags, NULL); | ||
| if (result != SQLITE_OK) { | ||
| NSString *errorString = FIRMessagingStringFromSQLiteResult(result); | ||
| NSString *errorMessage = | ||
| [NSString stringWithFormat:@"Could not open or create RMQ database at path %@, error: %@", | ||
| path, errorString]; | ||
| FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase, | ||
| @"%@", errorMessage); | ||
|
|
||
| // If the file existed, it might be corrupt. Let's remove it and fail. | ||
| if (fileExists) { | ||
| // This is synchronous, but it's on the database queue, so it's safe. | ||
| [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; | ||
| } | ||
| NSAssert(NO, errorMessage); | ||
| return; | ||
| } | ||
|
|
||
| if (!fileExists) { | ||
| // New database, create tables. | ||
| [self createTableWithName:kTableOutgoingRmqMessages command:kCreateTableOutgoingRmqMessages]; | ||
|
|
||
| [self createTableWithName:kTableLastRmqId command:kCreateTableLastRmqId]; | ||
| [self createTableWithName:kTableS2DRmqIds command:kCreateTableS2DRmqIds]; | ||
| } else { | ||
| // Calling sqlite3_open should create the database, since the file doesn't exist. | ||
| int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; | ||
| #ifdef SQLITE_OPEN_FILEPROTECTION_NONE | ||
| flags |= SQLITE_OPEN_FILEPROTECTION_NONE; | ||
| #endif | ||
| int result = sqlite3_open_v2([path UTF8String], &self -> _database, flags, NULL); | ||
| if (result != SQLITE_OK) { | ||
| NSString *errorString = FIRMessagingStringFromSQLiteResult(result); | ||
| NSString *errorMessage = | ||
| [NSString stringWithFormat:@"Could not create RMQ database at path %@, error: %@", path, | ||
| errorString]; | ||
| FIRMessagingLoggerError(kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingDatabase, | ||
| @"%@", errorMessage); | ||
| NSAssert(NO, errorMessage); | ||
|
Comment on lines
-528
to
-533
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
From linked issue: This highlighted |
||
| didOpenDatabase = NO; | ||
| } else { | ||
| [self updateDBWithStringRmqID]; | ||
| } | ||
| // Existing database, update schema if needed. | ||
| [self updateDBWithStringRmqID]; | ||
| } | ||
|
|
||
| if (didOpenDatabase) { | ||
| [self createTableWithName:kTableSyncMessages command:kCreateTableSyncMessages]; | ||
| } | ||
| // This table should exist in both new and old databases. | ||
| [self createTableWithName:kTableSyncMessages command:kCreateTableSyncMessages]; | ||
| }); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's good practice to handle the error that can occur when removing the item at the specified path. While the
NSAssertwill likely crash the app in debug builds, logging the error fromremoveItemAtPath:error:can provide valuable diagnostic information, especially in release builds where assertions are disabled and the app might attempt to recover on the next launch.