Skip to content

Commit 087bb95

Browse files
Prevent stale configuration data after iOS device restore (#15442)
1 parent 4f36a1c commit 087bb95

File tree

4 files changed

+35
-2
lines changed

4 files changed

+35
-2
lines changed

FirebaseRemoteConfig/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# Unreleased
2+
- [fixed] Fixed a bug where Remote Config does not work after a restore
3+
of a previous backup of the device. (#14459)
4+
- [fixed] Fixed a data race condition on the global database status flag
5+
by synchronizing all read and write operations. (#14715)
6+
17
# 12.3.0
28
- [fixed] Add missing GoogleUtilities dependency to fix SwiftPM builds when
39
building dynamically linked libraries. (#15276)

FirebaseRemoteConfig/Sources/FIRRemoteConfig.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ - (instancetype)initWithAppName:(NSString *)appName
160160

161161
// Initialize RCConfigContent if not already.
162162
_configContent = configContent;
163+
164+
// We must ensure the DBManager's asynchronous setup (which sets gIsNewDatabase)
165+
// completes before RCNConfigSettings tries to read that state for the resetUserDefaults logic.
166+
[_DBManager waitForDatabaseOperationQueue];
163167
_settings = [[RCNConfigSettings alloc] initWithDatabaseManager:_DBManager
164168
namespace:_FIRNamespace
165169
firebaseAppName:appName

FirebaseRemoteConfig/Sources/RCNConfigDBManager.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,8 @@ typedef void (^RCNDBLoadCompletion)(BOOL success,
130130

131131
/// Returns true if this a new install of the Config database.
132132
- (BOOL)isNewDatabase;
133+
134+
/// Blocks the calling thread until all pending database operations on the internal serial queue are
135+
/// completed. Used to enforce initialization order.
136+
- (void)waitForDatabaseOperationQueue;
133137
@end

FirebaseRemoteConfig/Sources/RCNConfigDBManager.m

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
/// The storage sub-directory that the Remote Config database resides in.
3939
static NSString *const RCNRemoteConfigStorageSubDirectory = @"Google/RemoteConfig";
4040

41+
/// Introduce a dedicated serial queue for gIsNewDatabase access.
42+
static dispatch_queue_t gIsNewDatabaseQueue;
43+
4144
/// Remote Config database path for deprecated V0 version.
4245
static NSString *RemoteConfigPathForOldDatabaseV0(void) {
4346
NSArray *dirPaths =
@@ -82,7 +85,9 @@ static BOOL RemoteConfigCreateFilePathIfNotExist(NSString *filePath) {
8285
}
8386
NSFileManager *fileManager = [NSFileManager defaultManager];
8487
if (![fileManager fileExistsAtPath:filePath]) {
85-
gIsNewDatabase = YES;
88+
dispatch_sync(gIsNewDatabaseQueue, ^{
89+
gIsNewDatabase = YES;
90+
});
8691
NSError *error;
8792
[fileManager createDirectoryAtPath:[filePath stringByDeletingLastPathComponent]
8893
withIntermediateDirectories:YES
@@ -119,6 +124,8 @@ + (instancetype)sharedInstance {
119124
static dispatch_once_t onceToken;
120125
static RCNConfigDBManager *sharedInstance;
121126
dispatch_once(&onceToken, ^{
127+
gIsNewDatabaseQueue = dispatch_queue_create("com.google.FirebaseRemoteConfig.gIsNewDatabase",
128+
DISPATCH_QUEUE_SERIAL);
122129
sharedInstance = [[RCNConfigDBManager alloc] init];
123130
});
124131
return sharedInstance;
@@ -1219,7 +1226,19 @@ - (BOOL)logErrorWithSQL:(const char *)SQL
12191226
}
12201227

12211228
- (BOOL)isNewDatabase {
1222-
return gIsNewDatabase;
1229+
__block BOOL isNew;
1230+
dispatch_sync(gIsNewDatabaseQueue, ^{
1231+
isNew = gIsNewDatabase;
1232+
});
1233+
return isNew;
1234+
}
1235+
1236+
- (void)waitForDatabaseOperationQueue {
1237+
// This dispatch_sync call ensures that all blocks queued before it on _databaseOperationQueue
1238+
// (including the createOrOpenDatabase setup block) execute and complete before this method
1239+
// returns.
1240+
dispatch_sync(_databaseOperationQueue, ^{
1241+
});
12231242
}
12241243

12251244
@end

0 commit comments

Comments
 (0)