[firestore] Use shared preferences for Firestore settings (#2453)

This commit is contained in:
Elliot Hesp
2019-08-07 15:38:47 +01:00
committed by Mike Diarmid
parent 42c20dbb45
commit 10a2cbf306
14 changed files with 200 additions and 73 deletions

View File

@@ -36,6 +36,7 @@ public class UniversalFirebasePreferences {
return getPreferences().contains(key);
}
// Boolean
public void setBooleanValue(String key, boolean value) {
getPreferences().edit().putBoolean(key, value).apply();
}
@@ -44,6 +45,16 @@ public class UniversalFirebasePreferences {
return getPreferences().getBoolean(key, defaultValue);
}
// Int
public void setIntValue(String key, int value) {
getPreferences().edit().putInt(key, value).apply();
}
public int getIntValue(String key, int defaultValue) {
return getPreferences().getInt(key, defaultValue);
}
// Long
public void setLongValue(String key, long value) {
getPreferences().edit().putLong(key, value).apply();
}
@@ -52,6 +63,7 @@ public class UniversalFirebasePreferences {
return getPreferences().getLong(key, defaultValue);
}
// String
public void setStringValue(String key, String value) {
getPreferences().edit().putString(key, value).apply();
}

View File

@@ -46,7 +46,7 @@ static RNFBPreferences *sharedInstance;
}
- (BOOL)getBooleanValue:(NSString *)key defaultValue:(BOOL)defaultValue {
if ([_userDefaults objectForKey:key] != nil) return defaultValue;
if ([_userDefaults objectForKey:key] == nil) return defaultValue;
return [_userDefaults boolForKey:key];
}
@@ -61,12 +61,12 @@ static RNFBPreferences *sharedInstance;
}
- (NSInteger *)getIntegerValue:(NSString *)key defaultValue:(NSInteger *)defaultValue {
if ([_userDefaults objectForKey:key] != nil) return defaultValue;
if ([_userDefaults objectForKey:key] == nil) return defaultValue;
return (NSInteger *) [_userDefaults integerForKey:key];
}
- (NSString *)getStringValue:(NSString *)key defaultValue:(NSString *)defaultValue {
if ([_userDefaults objectForKey:key] != nil) return defaultValue;
if ([_userDefaults objectForKey:key] == nil) return defaultValue;
return [_userDefaults stringForKey:key];
}

View File

@@ -20,13 +20,66 @@ package io.invertase.firebase.firestore;
import com.google.firebase.FirebaseApp;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.FirebaseFirestoreSettings;
import com.google.firebase.firestore.Query;
import java.util.HashMap;
import io.invertase.firebase.common.UniversalFirebasePreferences;
public class UniversalFirebaseFirestoreCommon {
private static HashMap<String, Boolean> settingsLock = new HashMap<>();
static FirebaseFirestore getFirestoreForApp(String appName) {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
return FirebaseFirestore.getInstance(firebaseApp);
FirebaseFirestore instance = FirebaseFirestore.getInstance(firebaseApp);
setFirestoreSettings(instance, appName);
return instance;
}
private static void setFirestoreSettings(FirebaseFirestore firebaseFirestore, String appName) {
// Ensure not already been set
if (settingsLock.containsKey(appName)) return;
UniversalFirebasePreferences preferences = UniversalFirebasePreferences.getSharedInstance();
FirebaseFirestoreSettings.Builder firestoreSettings = new FirebaseFirestoreSettings.Builder();
int cacheSizeBytes = preferences.getIntValue(
UniversalFirebaseFirestoreStatics.FIRESTORE_CACHE_SIZE + "_" + appName,
(int) firebaseFirestore.getFirestoreSettings().getCacheSizeBytes()
);
String host = preferences.getStringValue(
UniversalFirebaseFirestoreStatics.FIRESTORE_HOST + "_" + appName,
firebaseFirestore.getFirestoreSettings().getHost()
);
boolean persistence = preferences.getBooleanValue(
UniversalFirebaseFirestoreStatics.FIRESTORE_PERSISTENCE + "_" + appName,
firebaseFirestore.getFirestoreSettings().isPersistenceEnabled()
);
boolean ssl = preferences.getBooleanValue(
UniversalFirebaseFirestoreStatics.FIRESTORE_SSL + "_" + appName,
firebaseFirestore.getFirestoreSettings().isSslEnabled()
);
if (cacheSizeBytes == -1) {
firestoreSettings.setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED);
} else {
firestoreSettings.setCacheSizeBytes((long) cacheSizeBytes);
}
firestoreSettings.setHost(host);
firestoreSettings.setPersistenceEnabled(persistence);
firestoreSettings.setSslEnabled(ssl);
firebaseFirestore.setFirestoreSettings(firestoreSettings.build());
settingsLock.put(appName, true);
}
static Query getQueryForFirestore(

View File

@@ -23,6 +23,7 @@ import com.google.android.gms.tasks.Tasks;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreSettings;
import io.invertase.firebase.common.UniversalFirebaseModule;
import io.invertase.firebase.common.UniversalFirebasePreferences;
import java.util.Map;
import java.util.Objects;
@@ -45,45 +46,40 @@ public class UniversalFirebaseFirestoreModule extends UniversalFirebaseModule {
Task<Void> settings(String appName, Map<String, Object> settings) {
return Tasks.call(getExecutor(), () -> {
FirebaseFirestore firebaseFirestore = getFirestoreForApp(appName);
FirebaseFirestoreSettings.Builder firestoreSettings = new FirebaseFirestoreSettings.Builder();
// settings.cacheSizeBytes
if (settings.containsKey("cacheSizeBytes")) {
Double cacheSizeBytesDouble = (Double) settings.get("cacheSizeBytes");
int cacheSizeBytes = cacheSizeBytesDouble.intValue();
if (cacheSizeBytes == -1) {
firestoreSettings.setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED);
} else {
firestoreSettings.setCacheSizeBytes(cacheSizeBytes);
}
} else {
firestoreSettings.setCacheSizeBytes(firebaseFirestore.getFirestoreSettings().getCacheSizeBytes());
UniversalFirebasePreferences.getSharedInstance().setIntValue(
UniversalFirebaseFirestoreStatics.FIRESTORE_CACHE_SIZE + "_" + appName,
Objects.requireNonNull(cacheSizeBytesDouble).intValue()
);
}
// settings.host
if (settings.containsKey("host")) {
firestoreSettings.setHost((String) Objects.requireNonNull(settings.get("host")));
} else {
firestoreSettings.setHost(firebaseFirestore.getFirestoreSettings().getHost());
UniversalFirebasePreferences.getSharedInstance().setStringValue(
UniversalFirebaseFirestoreStatics.FIRESTORE_HOST + "_" + appName,
(String) settings.get("host")
);
}
// settings.persistence
if (settings.containsKey("persistence")) {
firestoreSettings.setPersistenceEnabled((boolean) settings.get("persistence"));
} else {
firestoreSettings.setPersistenceEnabled(firebaseFirestore.getFirestoreSettings().isPersistenceEnabled());
UniversalFirebasePreferences.getSharedInstance().setBooleanValue(
UniversalFirebaseFirestoreStatics.FIRESTORE_PERSISTENCE + "_" + appName,
(boolean) settings.get("persistence")
);
}
// settings.ssl
if (settings.containsKey("ssl")) {
firestoreSettings.setSslEnabled((boolean) settings.get("ssl"));
} else {
firestoreSettings.setSslEnabled(firebaseFirestore.getFirestoreSettings().isSslEnabled());
UniversalFirebasePreferences.getSharedInstance().setBooleanValue(
UniversalFirebaseFirestoreStatics.FIRESTORE_SSL + "_" + appName,
(boolean) settings.get("ssl")
);
}
firebaseFirestore.setFirestoreSettings(firestoreSettings.build());
return null;
});
}

View File

@@ -0,0 +1,25 @@
package io.invertase.firebase.firestore;
/*
* Copyright (c) 2016-present Invertase Limited & Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this library except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
public class UniversalFirebaseFirestoreStatics {
public static String FIRESTORE_CACHE_SIZE = "firebase_firestore_cache_size";
public static String FIRESTORE_HOST = "firebase_firestore_host";
public static String FIRESTORE_PERSISTENCE = "firebase_firestore_persistence";
public static String FIRESTORE_SSL = "firebase_firestore_ssl";
}

View File

@@ -20,8 +20,8 @@
#import <RNFBApp/RNFBSharedUtils.h>
#import <React/RCTBridgeModule.h>
#import <RNFBFirestoreQuery.h>
#import <RNFBFirestoreCommon.h>
#import <RNFBFirestoreSerialize.h>
#import "RNFBFirestoreCommon.h"
#import "RNFBFirestoreSerialize.h"
static NSString *const KEY_INCLUDE_METADATA_CHANGES = @"includeMetadataChanges";

View File

@@ -30,7 +30,7 @@ static NSString *const RNFB_FIRESTORE_COLLECTION_SYNC = @"firestore_collection_s
RCT_EXPORT_MODULE();
- (dispatch_queue_t)methodQueue {
return dispatch_queue_create("io.invertase.firebase.firestore", DISPATCH_QUEUE_SERIAL);
return [RNFBFirestoreCommon getFirestoreQueue];
}
+ (BOOL)requiresMainQueueSetup {

View File

@@ -21,8 +21,12 @@
@interface RNFBFirestoreCommon : NSObject
+ (dispatch_queue_t)getFirestoreQueue;
+ (FIRFirestore *)getFirestoreForApp:(FIRApp *)firebaseApp;
+ (void)setFirestoreSettings:(FIRFirestore *)firestore appName:(NSString *)appName;
+ (FIRDocumentReference *)getDocumentForFirestore:(FIRFirestore *)firestore path:(NSString *)path;
+ (FIRQuery *)getQueryForFirestore:(FIRFirestore *)firestore path:(NSString *)path type:(NSString *)type;
@@ -32,3 +36,8 @@
+ (NSArray *)getCodeAndMessage:(NSError *)error;
@end
extern NSString *const FIRESTORE_CACHE_SIZE;
extern NSString *const FIRESTORE_HOST;
extern NSString *const FIRESTORE_PERSISTENCE;
extern NSString *const FIRESTORE_SSL;

View File

@@ -17,13 +17,69 @@
*/
#import "RNFBFirestoreCommon.h"
#import "RNFBPreferences.h"
#import <RNFBApp/RNFBSharedUtils.h>
NSString *const FIRESTORE_CACHE_SIZE = @"firebase_firestore_cache_size";
NSString *const FIRESTORE_HOST = @"firebase_firestore_host";
NSString *const FIRESTORE_PERSISTENCE = @"firebase_firestore_persistence";
NSString *const FIRESTORE_SSL = @"firebase_firestore_ssl";
static __strong NSMutableDictionary *settingsLock;
@implementation RNFBFirestoreCommon
+ (FIRFirestore *)getFirestoreForApp
:(FIRApp *)app {
return [FIRFirestore firestoreForApp:app];
FIRFirestore *instance = [FIRFirestore firestoreForApp:app];
[self setFirestoreSettings:instance appName:[RNFBSharedUtils getAppJavaScriptName:app.name]];
return instance;
}
+ (dispatch_queue_t)getFirestoreQueue {
static dispatch_queue_t firestoreQueue;
static dispatch_once_t once;
dispatch_once(&once, ^{
firestoreQueue = dispatch_queue_create("io.invertase.firebase.firestore", DISPATCH_QUEUE_SERIAL);
});
return firestoreQueue;
}
+ (void)setFirestoreSettings:(FIRFirestore *)firestore appName:(NSString *)appName {
// Prevent setting if already set
if (settingsLock[appName]) {
return;
}
FIRFirestoreSettings *firestoreSettings = [[FIRFirestoreSettings alloc] init];
RNFBPreferences *preferences = [RNFBPreferences shared];
firestoreSettings.dispatchQueue = [self getFirestoreQueue];
NSString *cacheKey = [NSString stringWithFormat:@"%@_%@", FIRESTORE_CACHE_SIZE, appName];
NSInteger *size = [preferences getIntegerValue:cacheKey defaultValue:0];
if (size == (NSInteger *) -1) {
firestoreSettings.cacheSizeBytes = kFIRFirestoreCacheSizeUnlimited;
} else if (size == 0) {
firestoreSettings.cacheSizeBytes = firestore.settings.cacheSizeBytes;
} else {
firestoreSettings.cacheSizeBytes = (int64_t) size;
}
NSString *hostKey = [NSString stringWithFormat:@"%@_%@", FIRESTORE_HOST, appName];
firestoreSettings.host = [preferences getStringValue:hostKey defaultValue:firestore.settings.host];
NSString *persistenceKey = [NSString stringWithFormat:@"%@_%@", FIRESTORE_PERSISTENCE, appName];
firestoreSettings.persistenceEnabled = (BOOL) [preferences getBooleanValue:persistenceKey defaultValue:firestore.settings.persistenceEnabled];
NSString *sslKey = [NSString stringWithFormat:@"%@_%@", FIRESTORE_SSL, appName];
firestoreSettings.sslEnabled = (BOOL) [preferences getBooleanValue:sslKey defaultValue:firestore.settings.sslEnabled];
settingsLock[appName] = @(YES);
return;
}
+ (FIRDocumentReference *)getDocumentForFirestore

View File

@@ -19,8 +19,8 @@
#import <Firebase/Firebase.h>
#import <RNFBApp/RNFBSharedUtils.h>
#import <React/RCTBridgeModule.h>
#import <RNFBFirestoreCommon.h>
#import <RNFBFirestoreSerialize.h>
#import "RNFBFirestoreCommon.h"
#import "RNFBFirestoreSerialize.h"
@interface RNFBFirestoreDocumentModule : NSObject <RCTBridgeModule>

View File

@@ -30,7 +30,7 @@ static NSString *const RNFB_FIRESTORE_DOCUMENT_SYNC = @"firestore_document_sync_
RCT_EXPORT_MODULE();
- (dispatch_queue_t)methodQueue {
return dispatch_queue_create("io.invertase.firebase.firestore", DISPATCH_QUEUE_SERIAL);
return [RNFBFirestoreCommon getFirestoreQueue];
}
+ (BOOL)requiresMainQueueSetup {

View File

@@ -18,26 +18,17 @@
#import <React/RCTUtils.h>
#import "RNFBFirestoreModule.h"
#import "RNFBFirestoreCommon.h"
#import "RNFBPreferences.h"
@implementation RNFBFirestoreModule
#pragma mark -
#pragma mark Module Setup
static dispatch_queue_t firestoreQueue;
- (id)init {
self = [super init];
static dispatch_once_t once;
dispatch_once(&once, ^{
firestoreQueue = dispatch_queue_create("io.invertase.firebase.firestore", DISPATCH_QUEUE_SERIAL);
});
return self;
}
RCT_EXPORT_MODULE();
- (dispatch_queue_t)methodQueue {
return firestoreQueue;
return [RNFBFirestoreCommon getFirestoreQueue];
}
+ (BOOL)requiresMainQueueSetup {
@@ -87,44 +78,29 @@ RCT_EXPORT_METHOD(settings:
:(RCTPromiseResolveBlock)resolve
:(RCTPromiseRejectBlock)reject
) {
FIRFirestore *firestore = [RNFBFirestoreCommon getFirestoreForApp:firebaseApp];
FIRFirestoreSettings *firestoreSettings = [[FIRFirestoreSettings alloc] init];
NSString *appName = [RNFBSharedUtils getAppJavaScriptName:firebaseApp.name];
firestoreSettings.dispatchQueue = firestoreQueue;
if (settings[@"cacheSizeBytes"]) {
NSString *cacheKey = [NSString stringWithFormat:@"%@_%@", FIRESTORE_CACHE_SIZE, appName];
[[RNFBPreferences shared] setIntegerValue:cacheKey integerValue:[settings[@"cacheSizeBytes"] integerValue]];
}
if (settings[@"host"]) {
firestoreSettings.host = settings[@"host"];
} else {
firestoreSettings.host = firestore.settings.host;
NSString *hostKey = [NSString stringWithFormat:@"%@_%@", FIRESTORE_HOST, appName];
[[RNFBPreferences shared] setStringValue:hostKey stringValue:settings[@"host"]];
}
if (settings[@"persistence"]) {
firestoreSettings.persistenceEnabled = [settings[@"persistence"] boolValue];
} else {
firestoreSettings.persistenceEnabled = firestore.settings.persistenceEnabled;
NSString *persistenceKey = [NSString stringWithFormat:@"%@_%@", FIRESTORE_PERSISTENCE, appName];
[[RNFBPreferences shared] setBooleanValue:persistenceKey boolValue:[settings[@"persistence"] boolValue]];
}
if (settings[@"ssl"]) {
firestoreSettings.sslEnabled = [settings[@"ssl"] boolValue];
} else {
firestoreSettings.sslEnabled = firestore.settings.sslEnabled;
NSString *sslKey = [NSString stringWithFormat:@"%@_%@", FIRESTORE_SSL, appName];
[[RNFBPreferences shared] setBooleanValue:sslKey boolValue:[settings[@"ssl"] boolValue]];
}
if (settings[@"cacheSizeBytes"]) {
NSInteger cacheSizeBytes = [settings[@"cacheSizeBytes"] integerValue];
if (cacheSizeBytes == -1) {
firestoreSettings.cacheSizeBytes = kFIRFirestoreCacheSizeUnlimited;
} else {
// TODO Test this
firestoreSettings.cacheSizeBytes = (int) cacheSizeBytes;
}
} else {
firestoreSettings.cacheSizeBytes = firestore.settings.cacheSizeBytes;
}
firestore.settings = firestoreSettings;
resolve([NSNull null]);
}
@end

View File

@@ -20,8 +20,8 @@
#import <RNFBApp/RNFBSharedUtils.h>
#import <React/RCTBridgeModule.h>
#import <RNFBFirestoreQuery.h>
#import <RNFBFirestoreCommon.h>
#import <RNFBFirestoreSerialize.h>
#import "RNFBFirestoreSerialize.h"
#import "RNFBFirestoreCommon.h"
@interface RNFBFirestoreTransactionModule : NSObject <RCTBridgeModule>

View File

@@ -44,7 +44,7 @@ RCT_EXPORT_MODULE();
}
- (dispatch_queue_t)methodQueue {
return dispatch_queue_create("io.invertase.firebase.firestore", DISPATCH_QUEUE_SERIAL);
return [RNFBFirestoreCommon getFirestoreQueue];
}
- (void)dealloc {