[android][database] cleanup & implement .off() native functionality
This commit is contained in:
parent
e4d27029b9
commit
887823162a
|
@ -13,7 +13,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
|
|
||||||
import com.google.firebase.FirebaseApp;
|
import com.google.firebase.FirebaseApp;
|
||||||
import com.google.firebase.database.ChildEventListener;
|
|
||||||
import com.google.firebase.database.MutableData;
|
import com.google.firebase.database.MutableData;
|
||||||
import com.google.firebase.database.OnDisconnect;
|
import com.google.firebase.database.OnDisconnect;
|
||||||
import com.google.firebase.database.ServerValue;
|
import com.google.firebase.database.ServerValue;
|
||||||
|
@ -22,7 +21,6 @@ import com.google.firebase.database.DataSnapshot;
|
||||||
import com.google.firebase.database.DatabaseError;
|
import com.google.firebase.database.DatabaseError;
|
||||||
import com.google.firebase.database.FirebaseDatabase;
|
import com.google.firebase.database.FirebaseDatabase;
|
||||||
import com.google.firebase.database.DatabaseReference;
|
import com.google.firebase.database.DatabaseReference;
|
||||||
import com.google.firebase.database.ValueEventListener;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -33,40 +31,13 @@ import io.invertase.firebase.Utils;
|
||||||
|
|
||||||
public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
|
public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
|
||||||
private static final String TAG = "RNFirebaseDatabase";
|
private static final String TAG = "RNFirebaseDatabase";
|
||||||
private HashMap<String, ChildEventListener> childEventListeners;
|
private HashMap<String, RNFirebaseDatabaseReference> references = new HashMap<>();
|
||||||
private HashMap<String, ValueEventListener> valueEventListeners;
|
|
||||||
private HashMap<String, RNFirebaseDatabaseReference> references = new HashMap<String, RNFirebaseDatabaseReference>();
|
|
||||||
private SparseArray<RNFirebaseTransactionHandler> transactionHandlers = new SparseArray<>();
|
private SparseArray<RNFirebaseTransactionHandler> transactionHandlers = new SparseArray<>();
|
||||||
|
|
||||||
RNFirebaseDatabase(ReactApplicationContext reactContext) {
|
RNFirebaseDatabase(ReactApplicationContext reactContext) {
|
||||||
super(reactContext);
|
super(reactContext);
|
||||||
childEventListeners = new HashMap<String, ChildEventListener>();
|
|
||||||
valueEventListeners = new HashMap<String, ValueEventListener>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Boolean hasValueEventListener(String queryKey) {
|
|
||||||
return valueEventListeners.containsKey(queryKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
Boolean hasChildEventListener(String queryKey) {
|
|
||||||
return childEventListeners.containsKey(queryKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addValueEventListener(String queryKey, ValueEventListener listener) {
|
|
||||||
valueEventListeners.put(queryKey, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addChildEventListener(String queryKey, ChildEventListener listener) {
|
|
||||||
childEventListeners.put(queryKey, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeValueEventListener(String queryKey) {
|
|
||||||
valueEventListeners.remove(queryKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeChildEventListener(String queryKey) {
|
|
||||||
childEventListeners.remove(queryKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* REACT NATIVE METHODS
|
* REACT NATIVE METHODS
|
||||||
|
@ -427,17 +398,29 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
|
||||||
*/
|
*/
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void on(String appName, ReadableMap props) {
|
public void on(String appName, ReadableMap props) {
|
||||||
getInternalReferenceForApp(appName, props).on(
|
getInternalReferenceForApp(appName, props)
|
||||||
|
.on(
|
||||||
this,
|
this,
|
||||||
props.getString("eventType"),
|
props.getString("eventType"),
|
||||||
props.getMap("registration")
|
props.getMap("registration")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the specified event registration key.
|
||||||
|
* If the ref no longer has any listeners the the ref is removed.
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param eventRegistrationKey
|
||||||
|
*/
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void off(String appName, ReadableMap args) {
|
public void off(String key, String eventRegistrationKey) {
|
||||||
|
RNFirebaseDatabaseReference nativeRef = references.get(key);
|
||||||
|
nativeRef.removeEventListener(eventRegistrationKey);
|
||||||
|
|
||||||
|
if (!nativeRef.hasListeners()) {
|
||||||
|
references.remove(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -463,27 +446,6 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* React Method - returns this module name
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "RNFirebaseDatabase";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* React Native constants for RNFirebaseDatabase
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> getConstants() {
|
|
||||||
final Map<String, Object> constants = new HashMap<>();
|
|
||||||
constants.put("serverValueTimestamp", ServerValue.TIMESTAMP);
|
|
||||||
return constants;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a database instance for a specific firebase app instance
|
* Get a database instance for a specific firebase app instance
|
||||||
|
@ -533,6 +495,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
* @param appName
|
* @param appName
|
||||||
* @param props
|
* @param props
|
||||||
* @return
|
* @return
|
||||||
|
@ -657,4 +621,26 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
|
||||||
errorMap.putString("message", message);
|
errorMap.putString("message", message);
|
||||||
return errorMap;
|
return errorMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React Method - returns this module name
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "RNFirebaseDatabase";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React Native constants for RNFirebaseDatabase
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getConstants() {
|
||||||
|
final Map<String, Object> constants = new HashMap<>();
|
||||||
|
constants.put("serverValueTimestamp", ServerValue.TIMESTAMP);
|
||||||
|
return constants;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.invertase.firebase.database;
|
package io.invertase.firebase.database;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -23,20 +24,21 @@ import com.google.firebase.database.ValueEventListener;
|
||||||
import io.invertase.firebase.Utils;
|
import io.invertase.firebase.Utils;
|
||||||
|
|
||||||
class RNFirebaseDatabaseReference {
|
class RNFirebaseDatabaseReference {
|
||||||
private static final String TAG = "RNFirebaseDBReference";
|
|
||||||
|
|
||||||
private String key;
|
private String key;
|
||||||
private Query query;
|
private Query query;
|
||||||
private String path;
|
|
||||||
private String appName;
|
private String appName;
|
||||||
private ReactContext reactContext;
|
private ReactContext reactContext;
|
||||||
|
private static final String TAG = "RNFirebaseDBReference";
|
||||||
|
private HashMap<String, ChildEventListener> childEventListeners;
|
||||||
|
private HashMap<String, ValueEventListener> valueEventListeners;
|
||||||
|
|
||||||
Query getQuery() {
|
Query getQuery() {
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* @param app
|
* @param app
|
||||||
* @param refKey
|
* @param refKey
|
||||||
|
@ -46,9 +48,67 @@ class RNFirebaseDatabaseReference {
|
||||||
RNFirebaseDatabaseReference(ReactContext context, String app, String refKey, String refPath, ReadableArray modifiersArray) {
|
RNFirebaseDatabaseReference(ReactContext context, String app, String refKey, String refPath, ReadableArray modifiersArray) {
|
||||||
key = refKey;
|
key = refKey;
|
||||||
appName = app;
|
appName = app;
|
||||||
path = refPath;
|
|
||||||
reactContext = context;
|
reactContext = context;
|
||||||
query = buildDatabaseQueryAtPathAndModifiers(path, modifiersArray);
|
childEventListeners = new HashMap<String, ChildEventListener>();
|
||||||
|
valueEventListeners = new HashMap<String, ValueEventListener>();
|
||||||
|
query = buildDatabaseQueryAtPathAndModifiers(refPath, modifiersArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true/false whether this internal ref has a specific listener by eventRegistrationKey.
|
||||||
|
*
|
||||||
|
* @param eventRegistrationKey
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Boolean hasEventListener(String eventRegistrationKey) {
|
||||||
|
return valueEventListeners.containsKey(eventRegistrationKey) || childEventListeners.containsKey(eventRegistrationKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true/false whether this internal ref has any child or value listeners.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Boolean hasListeners() {
|
||||||
|
return valueEventListeners.size() > 0 || childEventListeners.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
* @param eventRegistrationKey
|
||||||
|
*/
|
||||||
|
void removeEventListener(String eventRegistrationKey) {
|
||||||
|
if (valueEventListeners.containsKey(eventRegistrationKey)) {
|
||||||
|
query.removeEventListener(valueEventListeners.get(eventRegistrationKey));
|
||||||
|
valueEventListeners.remove(eventRegistrationKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (childEventListeners.containsKey(eventRegistrationKey)) {
|
||||||
|
query.removeEventListener(childEventListeners.get(eventRegistrationKey));
|
||||||
|
childEventListeners.remove(eventRegistrationKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
* @param eventRegistrationKey
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
private void addEventListener(String eventRegistrationKey, ValueEventListener listener) {
|
||||||
|
valueEventListeners.put(eventRegistrationKey, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
|
* @param eventRegistrationKey
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
private void addEventListener(String eventRegistrationKey, ChildEventListener listener) {
|
||||||
|
childEventListeners.put(eventRegistrationKey, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,7 +131,6 @@ class RNFirebaseDatabaseReference {
|
||||||
};
|
};
|
||||||
|
|
||||||
query.addListenerForSingleValueEvent(onceValueEventListener);
|
query.addListenerForSingleValueEvent(onceValueEventListener);
|
||||||
|
|
||||||
Log.d(TAG, "Added OnceValueEventListener for key: " + key);
|
Log.d(TAG, "Added OnceValueEventListener for key: " + key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +219,8 @@ class RNFirebaseDatabaseReference {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
* @param registration
|
* @param registration
|
||||||
* @param eventType
|
* @param eventType
|
||||||
* @param database
|
* @param database
|
||||||
|
@ -168,7 +229,7 @@ class RNFirebaseDatabaseReference {
|
||||||
final String eventRegistrationKey = registration.getString("eventRegistrationKey");
|
final String eventRegistrationKey = registration.getString("eventRegistrationKey");
|
||||||
final String registrationCancellationKey = registration.getString("registrationCancellationKey");
|
final String registrationCancellationKey = registration.getString("registrationCancellationKey");
|
||||||
|
|
||||||
if (!database.hasChildEventListener(eventRegistrationKey)) {
|
if (!hasEventListener(eventRegistrationKey)) {
|
||||||
ChildEventListener childEventListener = new ChildEventListener() {
|
ChildEventListener childEventListener = new ChildEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
|
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
|
||||||
|
@ -200,25 +261,26 @@ class RNFirebaseDatabaseReference {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCancelled(DatabaseError error) {
|
public void onCancelled(DatabaseError error) {
|
||||||
query.removeEventListener(this);
|
removeEventListener(eventRegistrationKey);
|
||||||
database.removeChildEventListener(eventRegistrationKey);
|
|
||||||
handleDatabaseError(registration, error);
|
handleDatabaseError(registration, error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
database.addChildEventListener(eventRegistrationKey, childEventListener);
|
addEventListener(eventRegistrationKey, childEventListener);
|
||||||
query.addChildEventListener(childEventListener);
|
query.addChildEventListener(childEventListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TODO
|
||||||
|
*
|
||||||
* @param registration
|
* @param registration
|
||||||
*/
|
*/
|
||||||
private void addValueEventListener(final ReadableMap registration, final RNFirebaseDatabase database) {
|
private void addValueEventListener(final ReadableMap registration, final RNFirebaseDatabase database) {
|
||||||
final String eventRegistrationKey = registration.getString("eventRegistrationKey");
|
final String eventRegistrationKey = registration.getString("eventRegistrationKey");
|
||||||
final String registrationCancellationKey = registration.getString("registrationCancellationKey");
|
final String registrationCancellationKey = registration.getString("registrationCancellationKey");
|
||||||
|
|
||||||
if (!database.hasValueEventListener(eventRegistrationKey)) {
|
if (!hasEventListener(eventRegistrationKey)) {
|
||||||
ValueEventListener valueEventListener = new ValueEventListener() {
|
ValueEventListener valueEventListener = new ValueEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onDataChange(DataSnapshot dataSnapshot) {
|
public void onDataChange(DataSnapshot dataSnapshot) {
|
||||||
|
@ -227,13 +289,12 @@ class RNFirebaseDatabaseReference {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCancelled(DatabaseError error) {
|
public void onCancelled(DatabaseError error) {
|
||||||
query.removeEventListener(this);
|
removeEventListener(eventRegistrationKey);
|
||||||
database.removeValueEventListener(eventRegistrationKey);
|
|
||||||
handleDatabaseError(registration, error);
|
handleDatabaseError(registration, error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
database.addValueEventListener(eventRegistrationKey, valueEventListener);
|
addEventListener(eventRegistrationKey, valueEventListener);
|
||||||
query.addValueEventListener(valueEventListener);
|
query.addValueEventListener(valueEventListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,44 +332,6 @@ class RNFirebaseDatabaseReference {
|
||||||
Utils.sendEvent(reactContext, "database_sync_event", event);
|
Utils.sendEvent(reactContext, "database_sync_event", event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// todo cleanup below
|
|
||||||
|
|
||||||
// void removeEventListener(int listenerId, String eventName) {
|
|
||||||
// if ("value".equals(eventName)) {
|
|
||||||
// removeValueEventListener(listenerId);
|
|
||||||
// } else {
|
|
||||||
// removeChildEventListener(listenerId);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// boolean hasListeners() {
|
|
||||||
// return childEventListeners.size() > 0 || valueEventListeners.size() > 0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void cleanup() {
|
|
||||||
// Log.d(TAG, "cleaning up database reference " + this);
|
|
||||||
// this.removeChildEventListener(null);
|
|
||||||
// this.removeValueEventListener(null);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private void removeChildEventListener(Integer listenerId) {
|
|
||||||
// ChildEventListener listener = childEventListeners.get(listenerId);
|
|
||||||
// if (listener != null) {
|
|
||||||
// query.removeEventListener(listener);
|
|
||||||
// childEventListeners.remove(listenerId);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void removeValueEventListener(Integer listenerId) {
|
|
||||||
// ValueEventListener listener = valueEventListeners.get(listenerId);
|
|
||||||
// if (listener != null) {
|
|
||||||
// query.removeEventListener(listener);
|
|
||||||
// valueEventListeners.delete(listenerId);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
private Query buildDatabaseQueryAtPathAndModifiers(String path, ReadableArray modifiers) {
|
private Query buildDatabaseQueryAtPathAndModifiers(String path, ReadableArray modifiers) {
|
||||||
FirebaseDatabase firebaseDatabase = RNFirebaseDatabase.getDatabaseForApp(appName);
|
FirebaseDatabase firebaseDatabase = RNFirebaseDatabase.getDatabaseForApp(appName);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue