[android][database] cleanup & implement .off() native functionality

This commit is contained in:
Salakar 2017-08-16 21:35:58 +01:00
parent e4d27029b9
commit 887823162a
2 changed files with 120 additions and 111 deletions

View File

@ -13,7 +13,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.google.firebase.FirebaseApp;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.MutableData;
import com.google.firebase.database.OnDisconnect;
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.FirebaseDatabase;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.ValueEventListener;
import java.util.HashMap;
import java.util.List;
@ -33,40 +31,13 @@ import io.invertase.firebase.Utils;
public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
private static final String TAG = "RNFirebaseDatabase";
private HashMap<String, ChildEventListener> childEventListeners;
private HashMap<String, ValueEventListener> valueEventListeners;
private HashMap<String, RNFirebaseDatabaseReference> references = new HashMap<String, RNFirebaseDatabaseReference>();
private HashMap<String, RNFirebaseDatabaseReference> references = new HashMap<>();
private SparseArray<RNFirebaseTransactionHandler> transactionHandlers = new SparseArray<>();
RNFirebaseDatabase(ReactApplicationContext 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
@ -427,17 +398,29 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
*/
@ReactMethod
public void on(String appName, ReadableMap props) {
getInternalReferenceForApp(appName, props).on(
getInternalReferenceForApp(appName, props)
.on(
this,
props.getString("eventType"),
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
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
@ -533,6 +495,8 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
}
/**
* TODO
*
* @param appName
* @param props
* @return
@ -657,4 +621,26 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
errorMap.putString("message", message);
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;
}
}

View File

@ -1,5 +1,6 @@
package io.invertase.firebase.database;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
@ -23,20 +24,21 @@ import com.google.firebase.database.ValueEventListener;
import io.invertase.firebase.Utils;
class RNFirebaseDatabaseReference {
private static final String TAG = "RNFirebaseDBReference";
private String key;
private Query query;
private String path;
private String appName;
private ReactContext reactContext;
private static final String TAG = "RNFirebaseDBReference";
private HashMap<String, ChildEventListener> childEventListeners;
private HashMap<String, ValueEventListener> valueEventListeners;
Query getQuery() {
return query;
}
/**
* TODO
*
* @param context
* @param app
* @param refKey
@ -46,9 +48,67 @@ class RNFirebaseDatabaseReference {
RNFirebaseDatabaseReference(ReactContext context, String app, String refKey, String refPath, ReadableArray modifiersArray) {
key = refKey;
appName = app;
path = refPath;
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);
Log.d(TAG, "Added OnceValueEventListener for key: " + key);
}
@ -160,6 +219,8 @@ class RNFirebaseDatabaseReference {
/**
* TODO
*
* @param registration
* @param eventType
* @param database
@ -168,7 +229,7 @@ class RNFirebaseDatabaseReference {
final String eventRegistrationKey = registration.getString("eventRegistrationKey");
final String registrationCancellationKey = registration.getString("registrationCancellationKey");
if (!database.hasChildEventListener(eventRegistrationKey)) {
if (!hasEventListener(eventRegistrationKey)) {
ChildEventListener childEventListener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
@ -200,25 +261,26 @@ class RNFirebaseDatabaseReference {
@Override
public void onCancelled(DatabaseError error) {
query.removeEventListener(this);
database.removeChildEventListener(eventRegistrationKey);
removeEventListener(eventRegistrationKey);
handleDatabaseError(registration, error);
}
};
database.addChildEventListener(eventRegistrationKey, childEventListener);
addEventListener(eventRegistrationKey, childEventListener);
query.addChildEventListener(childEventListener);
}
}
/**
* TODO
*
* @param registration
*/
private void addValueEventListener(final ReadableMap registration, final RNFirebaseDatabase database) {
final String eventRegistrationKey = registration.getString("eventRegistrationKey");
final String registrationCancellationKey = registration.getString("registrationCancellationKey");
if (!database.hasValueEventListener(eventRegistrationKey)) {
if (!hasEventListener(eventRegistrationKey)) {
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
@ -227,13 +289,12 @@ class RNFirebaseDatabaseReference {
@Override
public void onCancelled(DatabaseError error) {
query.removeEventListener(this);
database.removeValueEventListener(eventRegistrationKey);
removeEventListener(eventRegistrationKey);
handleDatabaseError(registration, error);
}
};
database.addValueEventListener(eventRegistrationKey, valueEventListener);
addEventListener(eventRegistrationKey, valueEventListener);
query.addValueEventListener(valueEventListener);
}
}
@ -271,44 +332,6 @@ class RNFirebaseDatabaseReference {
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) {
FirebaseDatabase firebaseDatabase = RNFirebaseDatabase.getDatabaseForApp(appName);