[database][wip] misc multi-app

This commit is contained in:
Salakar 2017-08-02 10:38:30 +01:00
parent c9efb0087f
commit b935034592
8 changed files with 566 additions and 508 deletions

View File

@ -373,10 +373,9 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
ref.removeValue(listener); ref.removeValue(listener);
} }
// Push no longer required, handled in JS now.
/** /**
* Subcribe once to a firebase reference. * Subscribe once to a firebase reference.
* *
* @param appName * @param appName
* @param refId * @param refId
@ -387,15 +386,24 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
*/ */
@ReactMethod @ReactMethod
public void once(String appName, int refId, String path, ReadableArray modifiers, String eventName, Promise promise) { public void once(String appName, int refId, String path, ReadableArray modifiers, String eventName, Promise promise) {
RNFirebaseDatabaseReference internalRef = getInternalReferenceForApp(appName, refId, path, modifiers, false); getInternalReferenceForApp(appName, refId, path, modifiers, false).once(eventName, promise);
if (eventName.equals("value")) {
internalRef.addOnceValueEventListener(promise);
} else {
internalRef.addChildOnceEventListener(eventName, promise);
}
} }
/**
* Subscribe to real time events for the specified database path + modifiers
*
* @param appName
* @param refId
* @param path
* @param modifiers
* @param eventName
* @param promise
*/
@ReactMethod
public void on(String appName, int refId, String path, ReadableArray modifiers, String eventName, Promise promise) {
getInternalReferenceForApp(appName, refId, path, modifiers, true).on(eventName);
}
@ -422,6 +430,11 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
} }
} }
/**
* React Method - returns this module name
*
* @return
*/
@Override @Override
public String getName() { public String getName() {
return "RNFirebaseDatabase"; return "RNFirebaseDatabase";
@ -482,13 +495,27 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
return existingRef; return existingRef;
} }
// todo move to error util for use in other modules /**
static String getMessageWithService(String message, String service, String fullCode) { * Wrap a message string with the specified service name e.g. 'Database'
*
* @param message
* @param service
* @param fullCode
* @return
*/
private static String getMessageWithService(String message, String service, String fullCode) {
// Service: Error message (service/code). // Service: Error message (service/code).
return service + ": " + message + " (" + fullCode.toLowerCase() + ")."; return service + ": " + message + " (" + fullCode.toLowerCase() + ").";
} }
static String getCodeWithService(String service, String code) { /**
* Generate a service error code string e.g. 'DATABASE/PERMISSION-DENIED'
*
* @param service
* @param code
* @return
*/
private static String getCodeWithService(String service, String code) {
return service.toUpperCase() + "/" + code.toUpperCase(); return service.toUpperCase() + "/" + code.toUpperCase();
} }

View File

@ -1,504 +1,504 @@
package io.invertase.firebase.database; //package io.invertase.firebase.database;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.WritableNativeArray;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.MutableData;
import com.google.firebase.database.ServerValue;
import com.google.firebase.database.OnDisconnect;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.Transaction;
import io.invertase.firebase.Utils;
public class RNFirebaseDatabaseOld extends ReactContextBaseJavaModule {
// private static final String TAG = "RNFirebaseDatabase";
// private HashMap<Integer, RNFirebaseDatabaseReference> mReferences = new HashMap<>();
// private HashMap<String, RNFirebaseTransactionHandler> mTransactionHandlers = new HashMap<>();
// private FirebaseDatabase mFirebaseDatabase;
// //
// public RNFirebaseDatabaseOld(ReactApplicationContext reactContext) { //import java.util.Map;
// super(reactContext); //import java.util.List;
// mFirebaseDatabase = FirebaseDatabase.getInstance(); //import java.util.HashMap;
// }
// @Override
// public String getName() {
// return TAG;
// }
// // Persistence
// @ReactMethod
// public void enablePersistence(
// final Boolean enable,
// final Callback callback) {
// try {
// mFirebaseDatabase.setPersistenceEnabled(enable);
// } catch (DatabaseException t) {
// //
// } //import android.net.Uri;
//import android.os.AsyncTask;
//import android.util.Log;
// //
// WritableMap res = Arguments.createMap(); //import com.facebook.react.bridge.Callback;
// res.putString("status", "success"); //import com.facebook.react.bridge.Arguments;
// callback.invoke(null, res); //import com.facebook.react.bridge.WritableArray;
// } //import com.facebook.react.bridge.WritableMap;
//import com.facebook.react.bridge.ReadableMap;
// @ReactMethod //import com.facebook.react.bridge.ReactMethod;
// public void keepSynced( //import com.facebook.react.bridge.ReactContext;
// final String path, //import com.facebook.react.bridge.ReadableArray;
// final Boolean enable, //import com.facebook.react.bridge.ReactApplicationContext;
// final Callback callback) { //import com.facebook.react.bridge.ReactContextBaseJavaModule;
// DatabaseReference ref = mFirebaseDatabase.getReference(path); //import com.facebook.react.bridge.ReadableMapKeySetIterator;
// ref.keepSynced(enable);
// //
// WritableMap res = Arguments.createMap(); //import com.facebook.react.bridge.WritableNativeArray;
// res.putString("status", "success"); //import com.google.firebase.database.DataSnapshot;
// res.putString("path", path); //import com.google.firebase.database.MutableData;
// callback.invoke(null, res); //import com.google.firebase.database.ServerValue;
// } //import com.google.firebase.database.OnDisconnect;
//import com.google.firebase.database.DatabaseError;
// // RNFirebaseDatabase //import com.google.firebase.database.DatabaseReference;
// @ReactMethod //import com.google.firebase.database.FirebaseDatabase;
// public void set( //import com.google.firebase.database.DatabaseException;
// final String path, //import com.google.firebase.database.Transaction;
// final ReadableMap props,
// final Callback callback) {
// DatabaseReference ref = mFirebaseDatabase.getReference(path);
// Map<String, Object> m = Utils.recursivelyDeconstructReadableMap(props);
// //
// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() { //import io.invertase.firebase.Utils;
// @Override
// public void onComplete(DatabaseError error, DatabaseReference ref) {
// handleCallback("set", callback, error);
// }
// };
// //
// ref.setValue(m.get("value"), listener); //public class RNFirebaseDatabaseOld extends ReactContextBaseJavaModule {
// } //// private static final String TAG = "RNFirebaseDatabase";
//// private HashMap<Integer, RNFirebaseDatabaseReference> mReferences = new HashMap<>();
// @ReactMethod //// private HashMap<String, RNFirebaseTransactionHandler> mTransactionHandlers = new HashMap<>();
// public void priority( //// private FirebaseDatabase mFirebaseDatabase;
// final String path, ////
// final ReadableMap priority, //// public RNFirebaseDatabaseOld(ReactApplicationContext reactContext) {
// final Callback callback) { //// super(reactContext);
// DatabaseReference ref = mFirebaseDatabase.getReference(path); //// mFirebaseDatabase = FirebaseDatabase.getInstance();
// Map<String, Object> priorityMap = Utils.recursivelyDeconstructReadableMap(priority); //// }
// //
// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() { //// @Override
// @Override //// public String getName() {
// public void onComplete(DatabaseError error, DatabaseReference ref) { //// return TAG;
// handleCallback("priority", callback, error); //// }
// }
// };
// //
// ref.setPriority(priorityMap.get("value"), listener); //// // Persistence
// } //// @ReactMethod
//// public void enablePersistence(
//// final Boolean enable,
//// final Callback callback) {
//// try {
//// mFirebaseDatabase.setPersistenceEnabled(enable);
//// } catch (DatabaseException t) {
////
//// }
////
//// WritableMap res = Arguments.createMap();
//// res.putString("status", "success");
//// callback.invoke(null, res);
//// }
//
//// @ReactMethod
//// public void keepSynced(
//// final String path,
//// final Boolean enable,
//// final Callback callback) {
//// DatabaseReference ref = mFirebaseDatabase.getReference(path);
//// ref.keepSynced(enable);
////
//// WritableMap res = Arguments.createMap();
//// res.putString("status", "success");
//// res.putString("path", path);
//// callback.invoke(null, res);
//// }
//
//// // RNFirebaseDatabase
//// @ReactMethod
//// public void set(
//// final String path,
//// final ReadableMap props,
//// final Callback callback) {
//// DatabaseReference ref = mFirebaseDatabase.getReference(path);
//// Map<String, Object> m = Utils.recursivelyDeconstructReadableMap(props);
////
//// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
//// @Override
//// public void onComplete(DatabaseError error, DatabaseReference ref) {
//// handleCallback("set", callback, error);
//// }
//// };
////
//// ref.setValue(m.get("value"), listener);
//// }
//
//// @ReactMethod
//// public void priority(
//// final String path,
//// final ReadableMap priority,
//// final Callback callback) {
//// DatabaseReference ref = mFirebaseDatabase.getReference(path);
//// Map<String, Object> priorityMap = Utils.recursivelyDeconstructReadableMap(priority);
////
//// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
//// @Override
//// public void onComplete(DatabaseError error, DatabaseReference ref) {
//// handleCallback("priority", callback, error);
//// }
//// };
////
//// ref.setPriority(priorityMap.get("value"), listener);
//// }
////
//// @ReactMethod
//// public void withPriority(
//// final String path,
//// final ReadableMap data,
//// final ReadableMap priority,
//// final Callback callback) {
//// DatabaseReference ref = mFirebaseDatabase.getReference(path);
//// Map<String, Object> dataMap = Utils.recursivelyDeconstructReadableMap(data);
//// Map<String, Object> priorityMap = Utils.recursivelyDeconstructReadableMap(priority);
////
//// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
//// @Override
//// public void onComplete(DatabaseError error, DatabaseReference ref) {
//// handleCallback("withPriority", callback, error);
//// }
//// };
////
//// ref.setValue(dataMap.get("value"), priorityMap.get("value"), listener);
//// }
////
//// @ReactMethod
//// public void update(final String path,
//// final ReadableMap props,
//// final Callback callback) {
//// DatabaseReference ref = mFirebaseDatabase.getReference(path);
//// Map<String, Object> m = Utils.recursivelyDeconstructReadableMap(props);
////
//// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
//// @Override
//// public void onComplete(DatabaseError error, DatabaseReference ref) {
//// handleCallback("update", callback, error);
//// }
//// };
////
//// ref.updateChildren(m, listener);
//// }
//
//// @ReactMethod
//// public void remove(final String path,
//// final Callback callback) {
//// DatabaseReference ref = mFirebaseDatabase.getReference(path);
//// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
//// @Override
//// public void onComplete(DatabaseError error, DatabaseReference ref) {
//// handleCallback("remove", callback, error);
//// }
//// };
////
//// ref.removeValue(listener);
//// }
//
//// @ReactMethod
//// public void push(final String path,
//// final ReadableMap props,
//// final Callback callback) {
////
//// Log.d(TAG, "Called push with " + path);
//// DatabaseReference ref = mFirebaseDatabase.getReference(path);
//// DatabaseReference newRef = ref.push();
////
//// final Uri url = Uri.parse(newRef.toString());
//// final String newPath = url.getPath();
////
//// ReadableMapKeySetIterator iterator = props.keySetIterator();
//// if (iterator.hasNextKey()) {
//// Log.d(TAG, "Passed value to push");
//// // lame way to check if the `props` are empty
//// Map<String, Object> m = Utils.recursivelyDeconstructReadableMap(props);
////
//// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
//// @Override
//// public void onComplete(DatabaseError error, DatabaseReference ref) {
//// if (error != null) {
//// WritableMap err = Arguments.createMap();
//// err.putInt("code", error.getCode());
//// err.putString("details", error.getDetails());
//// err.putString("description", error.getMessage());
//// callback.invoke(err);
//// } else {
//// WritableMap res = Arguments.createMap();
//// res.putString("status", "success");
//// res.putString("ref", newPath);
//// callback.invoke(null, res);
//// }
//// }
//// };
////
//// newRef.setValue(m.get("value"), listener);
//// } else {
//// Log.d(TAG, "No value passed to push: " + newPath);
//// WritableMap res = Arguments.createMap();
//// res.putString("status", "success");
//// res.putString("ref", newPath);
//// callback.invoke(null, res);
//// }
//// }
//
//// /**
//// * @param path
//// * @param id
//// * @param applyLocally
//// */
//// @ReactMethod
//// public void startTransaction(final String path, final String id, final Boolean applyLocally) {
//// AsyncTask.execute(new Runnable() {
//// @Override
//// public void run() {
//// DatabaseReference transactionRef = FirebaseDatabase.getInstance().getReference(path);
////
//// transactionRef.runTransaction(new Transaction.Handler() {
//// @Override
//// public Transaction.Result doTransaction(MutableData mutableData) {
//// final WritableMap updatesMap = Arguments.createMap();
////
//// updatesMap.putString("id", id);
//// updatesMap.putString("type", "update");
////
//// if (!mutableData.hasChildren()) {
//// Utils.mapPutValue("value", mutableData.getValue(), updatesMap);
//// } else {
//// Object value = Utils.castValue(mutableData);
//// if (value instanceof WritableNativeArray) {
//// updatesMap.putArray("value", (WritableArray) value);
//// } else {
//// updatesMap.putMap("value", (WritableMap) value);
//// }
//// }
////
//// RNFirebaseTransactionHandler rnFirebaseTransactionHandler = new RNFirebaseTransactionHandler();
//// mTransactionHandlers.put(id, rnFirebaseTransactionHandler);
////
//// AsyncTask.execute(new Runnable() {
//// @Override
//// public void run() {
//// Utils.sendEvent(getReactApplicationContext(), "database_transaction_event", updatesMap);
//// }
//// });
////
//// try {
//// rnFirebaseTransactionHandler.await();
//// } catch (InterruptedException e) {
//// rnFirebaseTransactionHandler.interrupted = true;
//// return Transaction.abort();
//// }
////
//// if (rnFirebaseTransactionHandler.abort) {
//// return Transaction.abort();
//// }
////
//// mutableData.setValue(rnFirebaseTransactionHandler.value);
//// return Transaction.success(mutableData);
//// }
////
//// @Override
//// public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {
//// final WritableMap updatesMap = Arguments.createMap();
//// updatesMap.putString("id", id);
////
//// RNFirebaseTransactionHandler rnFirebaseTransactionHandler = mTransactionHandlers.get(id);
////
//// // TODO error conversion util for database to create web sdk codes based on DatabaseError
//// if (databaseError != null) {
//// updatesMap.putString("type", "error");
////
//// updatesMap.putInt("code", databaseError.getCode());
//// updatesMap.putString("message", databaseError.getMessage());
//// } else if (rnFirebaseTransactionHandler.interrupted) {
//// updatesMap.putString("type", "error");
////
//// updatesMap.putInt("code", 666);
//// updatesMap.putString("message", "RNFirebase transaction was interrupted, aborting.");
//// } else {
//// updatesMap.putString("type", "complete");
//// updatesMap.putBoolean("committed", committed);
//// updatesMap.putMap("snapshot", Utils.snapshotToMap(dataSnapshot));
//// }
////
//// Utils.sendEvent(getReactApplicationContext(), "database_transaction_event", updatesMap);
//// mTransactionHandlers.remove(id);
//// }
//// }, applyLocally);
//// }
//// });
//// }
////
//// /**
//// *
//// * @param id
//// * @param updates
//// */
//// @ReactMethod
//// public void tryCommitTransaction(final String id, final ReadableMap updates) {
//// Map<String, Object> updatesReturned = Utils.recursivelyDeconstructReadableMap(updates);
//// RNFirebaseTransactionHandler rnFirebaseTransactionHandler = mTransactionHandlers.get(id);
////
//// if (rnFirebaseTransactionHandler != null) {
//// rnFirebaseTransactionHandler.signalUpdateReceived(updatesReturned);
//// }
//// }
// //
// @ReactMethod // @ReactMethod
// public void withPriority( // public void on(final int refId, final String path, final ReadableArray modifiers, final int listenerId, final String eventName, final Callback callback) {
// final String path,
// final ReadableMap data,
// final ReadableMap priority,
// final Callback callback) {
// DatabaseReference ref = mFirebaseDatabase.getReference(path);
// Map<String, Object> dataMap = Utils.recursivelyDeconstructReadableMap(data);
// Map<String, Object> priorityMap = Utils.recursivelyDeconstructReadableMap(priority);
//
// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
// @Override
// public void onComplete(DatabaseError error, DatabaseReference ref) {
// handleCallback("withPriority", callback, error);
// }
// };
//
// ref.setValue(dataMap.get("value"), priorityMap.get("value"), listener);
// }
//
// @ReactMethod
// public void update(final String path,
// final ReadableMap props,
// final Callback callback) {
// DatabaseReference ref = mFirebaseDatabase.getReference(path);
// Map<String, Object> m = Utils.recursivelyDeconstructReadableMap(props);
//
// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
// @Override
// public void onComplete(DatabaseError error, DatabaseReference ref) {
// handleCallback("update", callback, error);
// }
// };
//
// ref.updateChildren(m, listener);
// }
// @ReactMethod
// public void remove(final String path,
// final Callback callback) {
// DatabaseReference ref = mFirebaseDatabase.getReference(path);
// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
// @Override
// public void onComplete(DatabaseError error, DatabaseReference ref) {
// handleCallback("remove", callback, error);
// }
// };
//
// ref.removeValue(listener);
// }
// @ReactMethod
// public void push(final String path,
// final ReadableMap props,
// final Callback callback) {
//
// Log.d(TAG, "Called push with " + path);
// DatabaseReference ref = mFirebaseDatabase.getReference(path);
// DatabaseReference newRef = ref.push();
//
// final Uri url = Uri.parse(newRef.toString());
// final String newPath = url.getPath();
//
// ReadableMapKeySetIterator iterator = props.keySetIterator();
// if (iterator.hasNextKey()) {
// Log.d(TAG, "Passed value to push");
// // lame way to check if the `props` are empty
// Map<String, Object> m = Utils.recursivelyDeconstructReadableMap(props);
//
// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
// @Override
// public void onComplete(DatabaseError error, DatabaseReference ref) {
// if (error != null) {
// WritableMap err = Arguments.createMap();
// err.putInt("code", error.getCode());
// err.putString("details", error.getDetails());
// err.putString("description", error.getMessage());
// callback.invoke(err);
// } else {
// WritableMap res = Arguments.createMap();
// res.putString("status", "success");
// res.putString("ref", newPath);
// callback.invoke(null, res);
// }
// }
// };
//
// newRef.setValue(m.get("value"), listener);
// } else {
// Log.d(TAG, "No value passed to push: " + newPath);
// WritableMap res = Arguments.createMap();
// res.putString("status", "success");
// res.putString("ref", newPath);
// callback.invoke(null, res);
// }
// }
// /**
// * @param path
// * @param id
// * @param applyLocally
// */
// @ReactMethod
// public void startTransaction(final String path, final String id, final Boolean applyLocally) {
// AsyncTask.execute(new Runnable() {
// @Override
// public void run() {
// DatabaseReference transactionRef = FirebaseDatabase.getInstance().getReference(path);
//
// transactionRef.runTransaction(new Transaction.Handler() {
// @Override
// public Transaction.Result doTransaction(MutableData mutableData) {
// final WritableMap updatesMap = Arguments.createMap();
//
// updatesMap.putString("id", id);
// updatesMap.putString("type", "update");
//
// if (!mutableData.hasChildren()) {
// Utils.mapPutValue("value", mutableData.getValue(), updatesMap);
// } else {
// Object value = Utils.castValue(mutableData);
// if (value instanceof WritableNativeArray) {
// updatesMap.putArray("value", (WritableArray) value);
// } else {
// updatesMap.putMap("value", (WritableMap) value);
// }
// }
//
// RNFirebaseTransactionHandler rnFirebaseTransactionHandler = new RNFirebaseTransactionHandler();
// mTransactionHandlers.put(id, rnFirebaseTransactionHandler);
//
// AsyncTask.execute(new Runnable() {
// @Override
// public void run() {
// Utils.sendEvent(getReactApplicationContext(), "database_transaction_event", updatesMap);
// }
// });
//
// try {
// rnFirebaseTransactionHandler.await();
// } catch (InterruptedException e) {
// rnFirebaseTransactionHandler.interrupted = true;
// return Transaction.abort();
// }
//
// if (rnFirebaseTransactionHandler.abort) {
// return Transaction.abort();
// }
//
// mutableData.setValue(rnFirebaseTransactionHandler.value);
// return Transaction.success(mutableData);
// }
//
// @Override
// public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {
// final WritableMap updatesMap = Arguments.createMap();
// updatesMap.putString("id", id);
//
// RNFirebaseTransactionHandler rnFirebaseTransactionHandler = mTransactionHandlers.get(id);
//
// // TODO error conversion util for database to create web sdk codes based on DatabaseError
// if (databaseError != null) {
// updatesMap.putString("type", "error");
//
// updatesMap.putInt("code", databaseError.getCode());
// updatesMap.putString("message", databaseError.getMessage());
// } else if (rnFirebaseTransactionHandler.interrupted) {
// updatesMap.putString("type", "error");
//
// updatesMap.putInt("code", 666);
// updatesMap.putString("message", "RNFirebase transaction was interrupted, aborting.");
// } else {
// updatesMap.putString("type", "complete");
// updatesMap.putBoolean("committed", committed);
// updatesMap.putMap("snapshot", Utils.snapshotToMap(dataSnapshot));
// }
//
// Utils.sendEvent(getReactApplicationContext(), "database_transaction_event", updatesMap);
// mTransactionHandlers.remove(id);
// }
// }, applyLocally);
// }
// });
// }
// /**
// *
// * @param id
// * @param updates
// */
// @ReactMethod
// public void tryCommitTransaction(final String id, final ReadableMap updates) {
// Map<String, Object> updatesReturned = Utils.recursivelyDeconstructReadableMap(updates);
// RNFirebaseTransactionHandler rnFirebaseTransactionHandler = mTransactionHandlers.get(id);
//
// if (rnFirebaseTransactionHandler != null) {
// rnFirebaseTransactionHandler.signalUpdateReceived(updatesReturned);
// }
// }
@ReactMethod
public void on(final int refId, final String path, final ReadableArray modifiers, final int listenerId, final String eventName, final Callback callback) {
RNFirebaseDatabaseReference ref = this.getDBHandle(refId, path, modifiers);
if (eventName.equals("value")) {
ref.addValueEventListener(listenerId);
} else {
ref.addChildEventListener(listenerId, eventName);
}
WritableMap resp = Arguments.createMap();
resp.putString("status", "success");
resp.putInt("refId", refId);
resp.putString("handle", path);
callback.invoke(null, resp);
}
// @ReactMethod
// public void once(final int refId, final String path, final ReadableArray modifiers, final String eventName, final Callback callback) {
// RNFirebaseDatabaseReference ref = this.getDBHandle(refId, path, modifiers); // RNFirebaseDatabaseReference ref = this.getDBHandle(refId, path, modifiers);
// //
// if (eventName.equals("value")) { // if (eventName.equals("value")) {
// ref.addOnceValueEventListener(callback); // ref.addValueEventListener(listenerId);
// } else { // } else {
// ref.addChildOnceEventListener(eventName, callback); // ref.addChildEventListener(listenerId, eventName);
// } // }
//
// WritableMap resp = Arguments.createMap();
// resp.putString("status", "success");
// resp.putInt("refId", refId);
// resp.putString("handle", path);
// callback.invoke(null, resp);
// } // }
//
/** //// @ReactMethod
* At the time of this writing, off() only gets called when there are no more subscribers to a given path. //// public void once(final int refId, final String path, final ReadableArray modifiers, final String eventName, final Callback callback) {
* `mListeners` might therefore be out of sync (though javascript isnt listening for those eventNames, so //// RNFirebaseDatabaseReference ref = this.getDBHandle(refId, path, modifiers);
* it doesn't really matter- just polluting the RN bridge a little more than necessary. ////
* off() should therefore clean *everything* up //// if (eventName.equals("value")) {
*/ //// ref.addOnceValueEventListener(callback);
@ReactMethod //// } else {
public void off( //// ref.addChildOnceEventListener(eventName, callback);
final int refId, //// }
final ReadableArray listeners, //// }
final Callback callback) { //
// /**
RNFirebaseDatabaseReference r = mReferences.get(refId); // * At the time of this writing, off() only gets called when there are no more subscribers to a given path.
// * `mListeners` might therefore be out of sync (though javascript isnt listening for those eventNames, so
if (r != null) { // * it doesn't really matter- just polluting the RN bridge a little more than necessary.
List<Object> listenersList = Utils.recursivelyDeconstructReadableArray(listeners); // * off() should therefore clean *everything* up
// */
for (Object l : listenersList) {
Map<String, Object> listener = (Map) l;
int listenerId = ((Double) listener.get("listenerId")).intValue();
String eventName = (String) listener.get("eventName");
r.removeEventListener(listenerId, eventName);
if (!r.hasListeners()) {
mReferences.remove(refId);
}
}
}
Log.d(TAG, "Removed listeners refId: " + refId + " ; count: " + listeners.size());
WritableMap resp = Arguments.createMap();
resp.putInt("refId", refId);
resp.putString("status", "success");
callback.invoke(null, resp);
}
// @ReactMethod // @ReactMethod
// public void onDisconnectSet(final String path, final ReadableMap props, final Callback callback) { // public void off(
// String type = props.getString("type"); // final int refId,
// DatabaseReference ref = mFirebaseDatabase.getReference(path); // final ReadableArray listeners,
// OnDisconnect od = ref.onDisconnect(); // final Callback callback) {
// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
// @Override
// public void onComplete(DatabaseError error, DatabaseReference ref) {
// handleCallback("onDisconnectSet", callback, error);
// }
// };
// //
// switch (type) {
// case "object":
// Map<String, Object> map = Utils.recursivelyDeconstructReadableMap(props.getMap("value"));
// od.setValue(map, listener);
// break;
// case "array":
// List<Object> list = Utils.recursivelyDeconstructReadableArray(props.getArray("value"));
// od.setValue(list, listener);
// break;
// case "string":
// od.setValue(props.getString("value"), listener);
// break;
// case "number":
// od.setValue(props.getDouble("value"), listener);
// break;
// case "boolean":
// od.setValue(props.getBoolean("value"), listener);
// break;
// case "null":
// od.setValue(null, listener);
// break;
// }
// }
//
// @ReactMethod
// public void onDisconnectUpdate(final String path, final ReadableMap props, final Callback callback) {
// DatabaseReference ref = mFirebaseDatabase.getReference(path);
// OnDisconnect od = ref.onDisconnect();
// Map<String, Object> map = Utils.recursivelyDeconstructReadableMap(props);
// od.updateChildren(map, new DatabaseReference.CompletionListener() {
// @Override
// public void onComplete(DatabaseError error, DatabaseReference ref) {
// handleCallback("onDisconnectUpdate", callback, error);
// }
// });
// }
//
// @ReactMethod
// public void onDisconnectRemove(final String path, final Callback callback) {
// DatabaseReference ref = mFirebaseDatabase.getReference(path);
//
// OnDisconnect od = ref.onDisconnect();
// od.removeValue(new DatabaseReference.CompletionListener() {
// @Override
// public void onComplete(DatabaseError error, DatabaseReference ref) {
// handleCallback("onDisconnectRemove", callback, error);
// }
// });
// }
//
// @ReactMethod
// public void onDisconnectCancel(final String path, final Callback callback) {
// DatabaseReference ref = mFirebaseDatabase.getReference(path);
//
// OnDisconnect od = ref.onDisconnect();
// od.cancel(new DatabaseReference.CompletionListener() {
// @Override
// public void onComplete(DatabaseError error, DatabaseReference ref) {
// handleCallback("onDisconnectCancel", callback, error);
// }
// });
// }
// @ReactMethod
// public void goOnline() {
// mFirebaseDatabase.goOnline();
// }
//
// @ReactMethod
// public void goOffline() {
// mFirebaseDatabase.goOffline();
// }
// private void handleCallback(
// final String methodName,
// final Callback callback,
// final DatabaseError databaseError) {
// if (databaseError != null) {
// WritableMap err = Arguments.createMap();
// err.putInt("code", databaseError.getCode());
// err.putString("details", databaseError.getDetails());
// err.putString("description", databaseError.getMessage());
// callback.invoke(err);
// } else {
// WritableMap res = Arguments.createMap();
// res.putString("status", "success");
// res.putString("method", methodName);
// callback.invoke(null, res);
// }
// }
// private RNFirebaseDatabaseReference getDBHandle(final int refId, final String path,
// final ReadableArray modifiers) {
// RNFirebaseDatabaseReference r = mReferences.get(refId); // RNFirebaseDatabaseReference r = mReferences.get(refId);
// //
// if (r == null) { // if (r != null) {
// ReactContext ctx = getReactApplicationContext(); // List<Object> listenersList = Utils.recursivelyDeconstructReadableArray(listeners);
// r = new RNFirebaseDatabaseReference(ctx, mFirebaseDatabase, refId, path, modifiers); //
// mReferences.put(refId, r); // for (Object l : listenersList) {
// Map<String, Object> listener = (Map) l;
// int listenerId = ((Double) listener.get("listenerId")).intValue();
// String eventName = (String) listener.get("eventName");
// r.removeEventListener(listenerId, eventName);
// if (!r.hasListeners()) {
// mReferences.remove(refId);
// }
// }
// } // }
// //
// return r; // Log.d(TAG, "Removed listeners refId: " + refId + " ; count: " + listeners.size());
// WritableMap resp = Arguments.createMap();
// resp.putInt("refId", refId);
// resp.putString("status", "success");
// callback.invoke(null, resp);
// } // }
//
// @Override //// @ReactMethod
// public Map<String, Object> getConstants() { //// public void onDisconnectSet(final String path, final ReadableMap props, final Callback callback) {
// final Map<String, Object> constants = new HashMap<>(); //// String type = props.getString("type");
// constants.put("serverValueTimestamp", ServerValue.TIMESTAMP); //// DatabaseReference ref = mFirebaseDatabase.getReference(path);
// return constants; //// OnDisconnect od = ref.onDisconnect();
// } //// DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
} //// @Override
//// public void onComplete(DatabaseError error, DatabaseReference ref) {
//// handleCallback("onDisconnectSet", callback, error);
//// }
//// };
////
//// switch (type) {
//// case "object":
//// Map<String, Object> map = Utils.recursivelyDeconstructReadableMap(props.getMap("value"));
//// od.setValue(map, listener);
//// break;
//// case "array":
//// List<Object> list = Utils.recursivelyDeconstructReadableArray(props.getArray("value"));
//// od.setValue(list, listener);
//// break;
//// case "string":
//// od.setValue(props.getString("value"), listener);
//// break;
//// case "number":
//// od.setValue(props.getDouble("value"), listener);
//// break;
//// case "boolean":
//// od.setValue(props.getBoolean("value"), listener);
//// break;
//// case "null":
//// od.setValue(null, listener);
//// break;
//// }
//// }
////
//// @ReactMethod
//// public void onDisconnectUpdate(final String path, final ReadableMap props, final Callback callback) {
//// DatabaseReference ref = mFirebaseDatabase.getReference(path);
//// OnDisconnect od = ref.onDisconnect();
//// Map<String, Object> map = Utils.recursivelyDeconstructReadableMap(props);
//// od.updateChildren(map, new DatabaseReference.CompletionListener() {
//// @Override
//// public void onComplete(DatabaseError error, DatabaseReference ref) {
//// handleCallback("onDisconnectUpdate", callback, error);
//// }
//// });
//// }
////
//// @ReactMethod
//// public void onDisconnectRemove(final String path, final Callback callback) {
//// DatabaseReference ref = mFirebaseDatabase.getReference(path);
////
//// OnDisconnect od = ref.onDisconnect();
//// od.removeValue(new DatabaseReference.CompletionListener() {
//// @Override
//// public void onComplete(DatabaseError error, DatabaseReference ref) {
//// handleCallback("onDisconnectRemove", callback, error);
//// }
//// });
//// }
////
//// @ReactMethod
//// public void onDisconnectCancel(final String path, final Callback callback) {
//// DatabaseReference ref = mFirebaseDatabase.getReference(path);
////
//// OnDisconnect od = ref.onDisconnect();
//// od.cancel(new DatabaseReference.CompletionListener() {
//// @Override
//// public void onComplete(DatabaseError error, DatabaseReference ref) {
//// handleCallback("onDisconnectCancel", callback, error);
//// }
//// });
//// }
//
//// @ReactMethod
//// public void goOnline() {
//// mFirebaseDatabase.goOnline();
//// }
////
//// @ReactMethod
//// public void goOffline() {
//// mFirebaseDatabase.goOffline();
//// }
//
//// private void handleCallback(
//// final String methodName,
//// final Callback callback,
//// final DatabaseError databaseError) {
//// if (databaseError != null) {
//// WritableMap err = Arguments.createMap();
//// err.putInt("code", databaseError.getCode());
//// err.putString("details", databaseError.getDetails());
//// err.putString("description", databaseError.getMessage());
//// callback.invoke(err);
//// } else {
//// WritableMap res = Arguments.createMap();
//// res.putString("status", "success");
//// res.putString("method", methodName);
//// callback.invoke(null, res);
//// }
//// }
//
//// private RNFirebaseDatabaseReference getDBHandle(final int refId, final String path,
//// final ReadableArray modifiers) {
//// RNFirebaseDatabaseReference r = mReferences.get(refId);
////
//// if (r == null) {
//// ReactContext ctx = getReactApplicationContext();
//// r = new RNFirebaseDatabaseReference(ctx, mFirebaseDatabase, refId, path, modifiers);
//// mReferences.put(refId, r);
//// }
////
//// return r;
//// }
//
//// @Override
//// public Map<String, Object> getConstants() {
//// final Map<String, Object> constants = new HashMap<>();
//// constants.put("serverValueTimestamp", ServerValue.TIMESTAMP);
//// return constants;
//// }
//}

View File

@ -55,6 +55,7 @@ public class RNFirebaseDatabaseReference {
/** /**
* Listen for a single 'value' event from firebase. * Listen for a single 'value' event from firebase.
*
* @param promise * @param promise
*/ */
void addOnceValueEventListener(final Promise promise) { void addOnceValueEventListener(final Promise promise) {
@ -78,6 +79,7 @@ public class RNFirebaseDatabaseReference {
/** /**
* Listen for single 'child_X' event from firebase. * Listen for single 'child_X' event from firebase.
*
* @param eventName * @param eventName
* @param promise * @param promise
*/ */
@ -130,14 +132,22 @@ public class RNFirebaseDatabaseReference {
} }
void on(String eventName) {
}
/**
*
* @param eventName
* @param promise
*/
void once(String eventName, Promise promise) {
if (eventName.equals("value")) {
addOnceValueEventListener(promise);
} else {
addChildOnceEventListener(eventName, promise);
}
}
// todo cleanup all below // todo cleanup all below
@ -212,7 +222,6 @@ public class RNFirebaseDatabaseReference {
} }
void removeEventListener(int listenerId, String eventName) { void removeEventListener(int listenerId, String eventName) {
if ("value".equals(eventName)) { if ("value".equals(eventName)) {
this.removeValueEventListener(listenerId); this.removeValueEventListener(listenerId);

View File

@ -11,18 +11,29 @@ import ModuleBase from './../../utils/ModuleBase';
/** /**
* @class Database * @class Database
*/ */
export default class Database extends ModuleBase { export default class Database extends ModuleBase {
constructor(firebaseApp: Object, options: Object = {}) { constructor(firebaseApp: Object, options: Object = {}) {
super(firebaseApp, options, 'Database', true); super(firebaseApp, options, 'Database', true);
this._serverTimeOffset = 0;
this._transactionHandler = new TransactionHandler(this); this._transactionHandler = new TransactionHandler(this);
if (this._options.persistence) this._native.setPersistence(this._options.persistence);
if (this._options.persistence) {
this._native.setPersistence(this._options.persistence);
}
// todo event & error listeners // todo event & error listeners
// todo serverTimeOffset event/listener - make ref natively and switch to events // todo serverTimeOffset event/listener - make ref natively and switch to events
// todo use nativeToJSError for on/off error events // todo use nativeToJSError for on/off error events
} }
/**
*
* @return {number}
*/
getServerTime() {
return new Date().getTime() + this._serverTimeOffset;
}
/** /**
* *
*/ */
@ -45,6 +56,14 @@ export default class Database extends ModuleBase {
ref(path: string) { ref(path: string) {
return new Reference(this, path); return new Reference(this, path);
} }
/**
* INTERNALS
*/
// todo handleDbEvent
// todo handleDbError
} }
export const statics = { export const statics = {

View File

@ -57,6 +57,7 @@ export default class Database extends ModuleBase {
const { listenerId, eventName } = listener; const { listenerId, eventName } = listener;
this.log.debug('on() : ', ref.refId, listenerId, eventName); this.log.debug('on() : ', ref.refId, listenerId, eventName);
this.references[refId] = ref; this.references[refId] = ref;
// todo pointless promise, doesn't need to return anything
return promisify('on', this._native)(refId, path, query.getModifiers(), listenerId, eventName); return promisify('on', this._native)(refId, path, query.getModifiers(), listenerId, eventName);
} }
@ -105,9 +106,9 @@ export default class Database extends ModuleBase {
/** /**
* INTERNALS * INTERNALS
*/ */
_getServerTime() { // _getServerTime() {
return new Date().getTime() + this.serverTimeOffset; // return new Date().getTime() + this.serverTimeOffset;
} // }
// /** // /**
// * Enabled / disable database persistence // * Enabled / disable database persistence

View File

@ -609,7 +609,6 @@ export default class Reference extends ReferenceBase {
if (!isFunction(successCallback)) throw new Error('Query.on failed: Second argument must be a valid function.'); if (!isFunction(successCallback)) throw new Error('Query.on failed: Second argument must be a valid function.');
if (arguments.length > 2 && !failureCallbackOrContext) throw new Error('Query.on failed: third argument must either be a cancel callback or a context object.'); if (arguments.length > 2 && !failureCallbackOrContext) throw new Error('Query.on failed: third argument must either be a cancel callback or a context object.');
// TODO this.log.debug('adding reference.on', this._refId, eventType);
let _failureCallback; let _failureCallback;
let _context; let _context;
@ -632,7 +631,7 @@ export default class Reference extends ReferenceBase {
failureCallbackOrContext(error); failureCallbackOrContext(error);
}; };
} }
// brb, helping someone
let _successCallback; let _successCallback;
if (_context) { if (_context) {

View File

@ -20,7 +20,7 @@ export default class TransactionHandler {
} }
/** /**
* Add a new transaction and begin starts it natively. * Add a new transaction and start it natively.
* @param reference * @param reference
* @param transactionUpdater * @param transactionUpdater
* @param onComplete * @param onComplete

View File

@ -26,6 +26,9 @@ const NATIVE_MODULE_EVENTS = {
], ],
Database: [ Database: [
'database_transaction_event', 'database_transaction_event',
'database_event',
'database_error',
'database_server_offset',
], ],
}; };