Merge pull request #881 from pocketgems/multiple_databases_3.3.0_upstream

Implement multiple database shard support
This commit is contained in:
Chris Bianca
2018-03-23 08:35:01 +00:00
committed by GitHub
26 changed files with 250 additions and 117 deletions

View File

@@ -53,16 +53,16 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param appName
*/
@ReactMethod
public void goOnline(String appName) {
getDatabaseForApp(appName).goOnline();
public void goOnline(String appName, String dbURL) {
getDatabaseForAppAndSetLogging(appName, dbURL).goOnline();
}
/**
* @param appName
*/
@ReactMethod
public void goOffline(String appName) {
getDatabaseForApp(appName).goOffline();
public void goOffline(String appName, String dbURL) {
getDatabaseForAppAndSetLogging(appName, dbURL).goOffline();
}
/**
@@ -70,8 +70,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param state
*/
@ReactMethod
public void setPersistence(String appName, Boolean state) {
getDatabaseForApp(appName).setPersistenceEnabled(state);
public void setPersistence(String appName, String dbURL, Boolean state) {
getDatabaseForAppAndSetLogging(appName, dbURL).setPersistenceEnabled(state);
}
/**
@@ -79,8 +79,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param size
*/
@ReactMethod
public void setPersistenceCacheSizeBytes(String appName, int size) {
getDatabaseForApp(appName).setPersistenceCacheSizeBytes((long) size);
public void setPersistenceCacheSizeBytes(String appName, String dbURL, int size) {
getDatabaseForAppAndSetLogging(appName, dbURL).setPersistenceCacheSizeBytes((long) size);
}
@@ -116,8 +116,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param state
*/
@ReactMethod
public void keepSynced(String appName, String key, String path, ReadableArray modifiers, Boolean state) {
getInternalReferenceForApp(appName, key, path, modifiers).getQuery().keepSynced(state);
public void keepSynced(String appName, String dbURL, String key, String path, ReadableArray modifiers, Boolean state) {
getInternalReferenceForApp(appName, dbURL, key, path, modifiers).getQuery().keepSynced(state);
}
@@ -130,7 +130,7 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param updates
*/
@ReactMethod
public void transactionTryCommit(String appName, int transactionId, ReadableMap updates) {
public void transactionTryCommit(String appName, String dbURL, int transactionId, ReadableMap updates) {
RNFirebaseTransactionHandler handler = transactionHandlers.get(transactionId);
if (handler != null) {
@@ -147,16 +147,16 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param applyLocally
*/
@ReactMethod
public void transactionStart(final String appName, final String path, final int transactionId, final Boolean applyLocally) {
public void transactionStart(final String appName, final String dbURL, final String path, final int transactionId, final Boolean applyLocally) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
DatabaseReference reference = getReferenceForAppPath(appName, path);
DatabaseReference reference = getReferenceForAppPath(appName, dbURL, path);
reference.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
final RNFirebaseTransactionHandler transactionHandler = new RNFirebaseTransactionHandler(transactionId, appName);
final RNFirebaseTransactionHandler transactionHandler = new RNFirebaseTransactionHandler(transactionId, appName, dbURL);
transactionHandlers.put(transactionId, transactionHandler);
final WritableMap updatesMap = transactionHandler.createUpdateMap(mutableData);
@@ -212,9 +212,9 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void onDisconnectSet(String appName, String path, ReadableMap props, final Promise promise) {
public void onDisconnectSet(String appName, String dbURL, String path, ReadableMap props, final Promise promise) {
String type = props.getString("type");
DatabaseReference ref = getReferenceForAppPath(appName, path);
DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path);
OnDisconnect onDisconnect = ref.onDisconnect();
DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
@@ -257,8 +257,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void onDisconnectUpdate(String appName, String path, ReadableMap props, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, path);
public void onDisconnectUpdate(String appName, String dbURL, String path, ReadableMap props, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path);
OnDisconnect ondDisconnect = ref.onDisconnect();
Map<String, Object> map = Utils.recursivelyDeconstructReadableMap(props);
@@ -279,8 +279,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void onDisconnectRemove(String appName, String path, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, path);
public void onDisconnectRemove(String appName, String dbURL, String path, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path);
OnDisconnect onDisconnect = ref.onDisconnect();
onDisconnect.removeValue(new DatabaseReference.CompletionListener() {
@@ -299,8 +299,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void onDisconnectCancel(String appName, String path, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, path);
public void onDisconnectCancel(String appName, String dbURL, String path, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path);
OnDisconnect onDisconnect = ref.onDisconnect();
onDisconnect.cancel(new DatabaseReference.CompletionListener() {
@@ -318,8 +318,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void set(String appName, String path, ReadableMap props, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, path);
public void set(String appName, String dbURL, String path, ReadableMap props, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path);
Object value = Utils.recursivelyDeconstructReadableMap(props).get("value");
DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
@@ -339,8 +339,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void setPriority(String appName, String path, ReadableMap priority, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, path);
public void setPriority(String appName, String dbURL, String path, ReadableMap priority, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path);
Object priorityValue = Utils.recursivelyDeconstructReadableMap(priority).get("value");
DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
@@ -361,8 +361,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void setWithPriority(String appName, String path, ReadableMap data, ReadableMap priority, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, path);
public void setWithPriority(String appName, String dbURL, String path, ReadableMap data, ReadableMap priority, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path);
Object dataValue = Utils.recursivelyDeconstructReadableMap(data).get("value");
Object priorityValue = Utils.recursivelyDeconstructReadableMap(priority).get("value");
@@ -383,8 +383,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void update(String appName, String path, ReadableMap props, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, path);
public void update(String appName, String dbURL, String path, ReadableMap props, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path);
Map<String, Object> updates = Utils.recursivelyDeconstructReadableMap(props);
DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
@@ -403,8 +403,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void remove(String appName, String path, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, path);
public void remove(String appName, String dbURL, String path, final Promise promise) {
DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path);
DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
@Override
@@ -428,8 +428,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void once(String appName, String key, String path, ReadableArray modifiers, String eventType, Promise promise) {
getInternalReferenceForApp(appName, key, path, modifiers).once(eventType, promise);
public void once(String appName, String dbURL, String key, String path, ReadableArray modifiers, String eventType, Promise promise) {
getInternalReferenceForApp(appName, dbURL, key, path, modifiers).once(eventType, promise);
}
/**
@@ -439,8 +439,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param props ReadableMap
*/
@ReactMethod
public void on(String appName, ReadableMap props) {
getCachedInternalReferenceForApp(appName, props)
public void on(String appName, String dbURL, ReadableMap props) {
getCachedInternalReferenceForApp(appName, dbURL, props)
.on(
props.getString("eventType"),
props.getMap("registration")
@@ -494,11 +494,30 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* Get a database instance for a specific firebase app instance
*
* @param appName
* @param dbURL
* @return
*/
private FirebaseDatabase getDatabaseForApp(String appName) {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance(firebaseApp);
public static FirebaseDatabase getDatabaseForApp(String appName, String dbURL) {
FirebaseDatabase firebaseDatabase;
if(dbURL != null && dbURL.length() > 0) {
firebaseDatabase = FirebaseDatabase.getInstance(dbURL);
} else {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
firebaseDatabase = FirebaseDatabase.getInstance(firebaseApp);
}
return firebaseDatabase;
}
/**
* Get a database instance for a specific firebase app instance and enable/disable logging
*
* @param appName
* @param dbURL
* @return
*/
private FirebaseDatabase getDatabaseForAppAndSetLogging(String appName, String dbURL) {
FirebaseDatabase firebaseDatabase = RNFirebaseDatabase.getDatabaseForApp(appName, dbURL);
Boolean logLevel = loggingLevelSet.get(firebaseDatabase.getApp().getName());
if (enableLogging && (logLevel == null || !logLevel)) {
@@ -535,8 +554,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param path
* @return
*/
private DatabaseReference getReferenceForAppPath(String appName, String path) {
return getDatabaseForApp(appName).getReference(path);
private DatabaseReference getReferenceForAppPath(String appName, String dbURL, String path) {
return getDatabaseForAppAndSetLogging(appName, dbURL).getReference(path);
}
/**
@@ -548,10 +567,11 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param modifiers
* @return
*/
private RNFirebaseDatabaseReference getInternalReferenceForApp(String appName, String key, String path, ReadableArray modifiers) {
private RNFirebaseDatabaseReference getInternalReferenceForApp(String appName, String dbURL, String key, String path, ReadableArray modifiers) {
return new RNFirebaseDatabaseReference(
getReactApplicationContext(),
appName,
dbURL,
key,
path,
modifiers
@@ -565,7 +585,7 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param props
* @return
*/
private RNFirebaseDatabaseReference getCachedInternalReferenceForApp(String appName, ReadableMap props) {
private RNFirebaseDatabaseReference getCachedInternalReferenceForApp(String appName, String dbURL, ReadableMap props) {
String key = props.getString("key");
String path = props.getString("path");
ReadableArray modifiers = props.getArray("modifiers");
@@ -573,7 +593,7 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
RNFirebaseDatabaseReference existingRef = references.get(key);
if (existingRef == null) {
existingRef = getInternalReferenceForApp(appName, key, path, modifiers);
existingRef = getInternalReferenceForApp(appName, dbURL, key, path, modifiers);
references.put(key, existingRef);
}

View File

@@ -28,6 +28,7 @@ class RNFirebaseDatabaseReference {
private String key;
private Query query;
private String appName;
private String dbURL;
private ReactContext reactContext;
private static final String TAG = "RNFirebaseDBReference";
private HashMap<String, ChildEventListener> childEventListeners = new HashMap<>();
@@ -43,10 +44,11 @@ class RNFirebaseDatabaseReference {
* @param refPath
* @param modifiersArray
*/
RNFirebaseDatabaseReference(ReactContext context, String app, String refKey, String refPath, ReadableArray modifiersArray) {
RNFirebaseDatabaseReference(ReactContext context, String app, String url, String refKey, String refPath, ReadableArray modifiersArray) {
key = refKey;
query = null;
appName = app;
dbURL = url;
reactContext = context;
buildDatabaseQueryAtPathAndModifiers(refPath, modifiersArray);
}
@@ -346,9 +348,7 @@ class RNFirebaseDatabaseReference {
* @return
*/
private void buildDatabaseQueryAtPathAndModifiers(String path, ReadableArray modifiers) {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance(firebaseApp);
FirebaseDatabase firebaseDatabase = RNFirebaseDatabase.getDatabaseForApp(appName, dbURL);
query = firebaseDatabase.getReference(path);
List<Object> modifiersList = Utils.recursivelyDeconstructReadableArray(modifiers);

View File

@@ -21,6 +21,7 @@ import io.invertase.firebase.Utils;
public class RNFirebaseTransactionHandler {
private int transactionId;
private String appName;
private String dbURL;
private final ReentrantLock lock;
private final Condition condition;
private Map<String, Object> data;
@@ -31,8 +32,9 @@ public class RNFirebaseTransactionHandler {
boolean abort = false;
boolean timeout = false;
RNFirebaseTransactionHandler(int id, String app) {
RNFirebaseTransactionHandler(int id, String app, String url) {
appName = app;
dbURL = url;
transactionId = id;
lock = new ReentrantLock();
condition = lock.newCondition();
@@ -107,6 +109,7 @@ public class RNFirebaseTransactionHandler {
// all events get distributed js side based on app name
updatesMap.putString("appName", appName);
updatesMap.putString("dbURL", dbURL);
if (!updatesData.hasChildren()) {
Utils.mapPutValue("value", updatesData.getValue(), updatesMap);
@@ -129,6 +132,7 @@ public class RNFirebaseTransactionHandler {
resultMap.putInt("id", transactionId);
resultMap.putString("appName", appName);
resultMap.putString("dbURL", dbURL);
resultMap.putBoolean("timeout", timeout);
resultMap.putBoolean("committed", committed);