@@ -501,7 +501,7 @@ - (void)openDatabase {
501501#ifdef SQLITE_OPEN_FILEPROTECTION_NONE
502502 flags |= SQLITE_OPEN_FILEPROTECTION_NONE;
503503#endif
504- int result = sqlite3_open_v2 ([path UTF8String ], &self -> _database, flags, NULL );
504+ int result = sqlite3_open_v2 ([path UTF8String ], &self-> _database , flags, NULL );
505505 if (result != SQLITE_OK) {
506506 NSString *errorString = FIRMessagingStringFromSQLiteResult (result);
507507 NSString *errorMessage = [NSString
@@ -517,21 +517,41 @@ - (void)openDatabase {
517517 [self createTableWithName: kTableLastRmqId command: kCreateTableLastRmqId ];
518518 [self createTableWithName: kTableS2DRmqIds command: kCreateTableS2DRmqIds ];
519519 } else {
520- // Calling sqlite3_open should create the database, since the file doesn't exist .
520+ // The file exists, try to open it. If it fails, it might be corrupt .
521521 int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
522522#ifdef SQLITE_OPEN_FILEPROTECTION_NONE
523523 flags |= SQLITE_OPEN_FILEPROTECTION_NONE;
524524#endif
525- int result = sqlite3_open_v2 ([path UTF8String ], &self -> _database, flags, NULL );
525+ int result = sqlite3_open_v2 ([path UTF8String ], &self->_database , flags, NULL );
526+
527+ // If opening the database failed, it might be corrupt. Try to recover by deleting and
528+ // recreating it.
526529 if (result != SQLITE_OK) {
527- NSString *errorString = FIRMessagingStringFromSQLiteResult (result);
528- NSString *errorMessage =
529- [NSString stringWithFormat: @" Could not create RMQ database at path %@ , error: %@ " , path,
530- errorString];
531- FIRMessagingLoggerError (kFIRMessagingMessageCodeRmq2PersistentStoreErrorCreatingDatabase ,
532- @" %@ " , errorMessage);
533- NSAssert (NO , errorMessage);
534- didOpenDatabase = NO ;
530+ FIRMessagingLoggerWarn (kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase ,
531+ @" Could not open RMQ database at path: %@ . "
532+ " Will delete and try to recreate it." ,
533+ path);
534+ [[NSFileManager defaultManager ] removeItemAtPath: path error: nil ];
535+ // After deleting, try to open it again.
536+ result = sqlite3_open_v2 ([path UTF8String ], &self->_database , flags, NULL );
537+ // If it still fails after the recovery attempt, then assert and crash.
538+ if (result != SQLITE_OK) {
539+ NSString *errorString = FIRMessagingStringFromSQLiteResult (result);
540+ NSString *errorMessage = [NSString
541+ stringWithFormat: @" Could not open or create RMQ database at path %@ , error: %@ " , path,
542+ errorString];
543+ FIRMessagingLoggerError (kFIRMessagingMessageCodeRmq2PersistentStoreErrorOpeningDatabase ,
544+ @" %@ " , errorMessage);
545+ NSAssert (NO , errorMessage);
546+ didOpenDatabase = NO ; // Still failed, so indicate database did not open.
547+ } else {
548+ // Successfully recreated after corruption, so treat as a new database for table creation.
549+ didOpenDatabase = YES ; // Indicate successful opening after recreation.
550+ [self createTableWithName: kTableOutgoingRmqMessages
551+ command: kCreateTableOutgoingRmqMessages ];
552+ [self createTableWithName: kTableLastRmqId command: kCreateTableLastRmqId ];
553+ [self createTableWithName: kTableS2DRmqIds command: kCreateTableS2DRmqIds ];
554+ }
535555 } else {
536556 [self updateDBWithStringRmqID ];
537557 }
0 commit comments