2
0
mirror of synced 2025-02-20 18:18:10 +00:00

[android] refactor and formatting cleanup

This commit is contained in:
Salakar 2018-08-04 21:57:06 +01:00
parent edf28b9a6d
commit d2bc8543bb
47 changed files with 1974 additions and 1032 deletions

View File

@ -1,30 +1,30 @@
package io.invertase.firebase;
import android.util.Log;
import android.app.Activity;
import android.content.IntentSender;
import android.util.Log;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.ArrayList;
// react
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
// play services
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// react
// play services
@SuppressWarnings("WeakerAccess")
public class RNFirebaseModule extends ReactContextBaseJavaModule {
private static final String TAG = "RNFirebase";
@ -103,7 +103,9 @@ public class RNFirebaseModule extends ReactContextBaseJavaModule {
if (status != ConnectionResult.SUCCESS && gapi.isUserResolvableError(status)) {
Activity activity = getCurrentActivity();
if (activity != null) {
gapi.getErrorDialog(activity, status, status).show();
gapi
.getErrorDialog(activity, status, status)
.show();
}
}
}
@ -113,7 +115,9 @@ public class RNFirebaseModule extends ReactContextBaseJavaModule {
*/
@ReactMethod
public void resolutionForPlayServices() {
int status = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getReactApplicationContext());
int status = GoogleApiAvailability
.getInstance()
.isGooglePlayServicesAvailable(getReactApplicationContext());
ConnectionResult connectionResult = new ConnectionResult(status);
if (!connectionResult.isSuccess() && connectionResult.hasResolution()) {

View File

@ -8,9 +8,9 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewManager;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@SuppressWarnings("unused")
public class RNFirebasePackage implements ReactPackage {

View File

@ -1,9 +1,7 @@
package io.invertase.firebase;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import com.facebook.react.bridge.Arguments;
@ -48,7 +46,9 @@ public class Utils {
if (value == null) {
map.putNull(key);
} else {
String type = value.getClass().getName();
String type = value
.getClass()
.getName();
switch (type) {
case "java.lang.Boolean":
map.putBoolean(key, (Boolean) value);
@ -159,7 +159,9 @@ public class Utils {
}
public static int getResId(Context ctx, String resName) {
int resourceId = ctx.getResources().getIdentifier(resName, "string", ctx.getPackageName());
int resourceId = ctx
.getResources()
.getIdentifier(resName, "string", ctx.getPackageName());
if (resourceId == 0) {
Log.e(TAG, "resource " + resName + " could not be found");
}

View File

@ -18,6 +18,13 @@ import java.util.Map;
public class RNFirebaseAdMob extends ReactContextBaseJavaModule {
private static final String TAG = "RNFirebaseAdMob";
private HashMap<String, RNFirebaseAdmobInterstitial> interstitials = new HashMap<>();
private HashMap<String, RNFirebaseAdMobRewardedVideo> rewardedVideos = new HashMap<>();
public RNFirebaseAdMob(ReactApplicationContext reactContext) {
super(reactContext);
Log.d(TAG, "New instance");
}
ReactApplicationContext getContext() {
return getReactApplicationContext();
@ -27,14 +34,6 @@ public class RNFirebaseAdMob extends ReactContextBaseJavaModule {
return getCurrentActivity();
}
private HashMap<String, RNFirebaseAdmobInterstitial> interstitials = new HashMap<>();
private HashMap<String, RNFirebaseAdMobRewardedVideo> rewardedVideos = new HashMap<>();
public RNFirebaseAdMob(ReactApplicationContext reactContext) {
super(reactContext);
Log.d(TAG, "New instance");
}
@Override
public String getName() {
return TAG;
@ -53,7 +52,9 @@ public class RNFirebaseAdMob extends ReactContextBaseJavaModule {
@ReactMethod
public void interstitialLoadAd(String adUnit, ReadableMap request) {
RNFirebaseAdmobInterstitial interstitial = getOrCreateInterstitial(adUnit);
interstitial.loadAd(RNFirebaseAdMobUtils.buildRequest(request).build());
interstitial.loadAd(RNFirebaseAdMobUtils
.buildRequest(request)
.build());
}
@ReactMethod
@ -65,7 +66,9 @@ public class RNFirebaseAdMob extends ReactContextBaseJavaModule {
@ReactMethod
public void rewardedVideoLoadAd(String adUnit, ReadableMap request) {
RNFirebaseAdMobRewardedVideo rewardedVideo = getOrCreateRewardedVideo(adUnit);
rewardedVideo.loadAd(RNFirebaseAdMobUtils.buildRequest(request).build());
rewardedVideo.loadAd(RNFirebaseAdMobUtils
.buildRequest(request)
.build());
}
@ReactMethod
@ -75,7 +78,6 @@ public class RNFirebaseAdMob extends ReactContextBaseJavaModule {
}
/**
*
* @param adUnit
* @return
*/
@ -89,7 +91,6 @@ public class RNFirebaseAdMob extends ReactContextBaseJavaModule {
}
/**
*
* @param adUnit
* @return
*/

View File

@ -23,38 +23,15 @@ public class RNFirebaseAdMobBanner extends SimpleViewManager<ReactViewGroup> {
public static final String REACT_CLASS = "RNFirebaseAdMobBanner";
public static final String BANNER_EVENT = "onBannerEvent";
public enum Events {
EVENT_AD_SIZE_CHANGE("onSizeChange"),
EVENT_AD_LOADED("onAdLoaded"),
EVENT_AD_FAILED_TO_LOAD("onAdFailedToLoad"),
EVENT_AD_OPENED("onAdOpened"),
EVENT_AD_CLOSED("onAdClosed"),
EVENT_AD_LEFT_APPLICATION("onAdLeftApplication");
private final String event;
Events(final String name) {
event = name;
}
@Override
public String toString() {
return event;
}
}
private ThemedReactContext context;
private ReactViewGroup viewGroup;
private RCTEventEmitter emitter;
private Boolean requested = false;
// Internal prop values
private AdRequest.Builder request;
private AdSize size;
private String unitId;
@Override
public String getName() {
return REACT_CLASS;
@ -197,15 +174,22 @@ public class RNFirebaseAdMobBanner extends SimpleViewManager<ReactViewGroup> {
int left = adView.getLeft();
int top = adView.getTop();
int width = adView.getAdSize().getWidthInPixels(context);
int height = adView.getAdSize().getHeightInPixels(context);
int width = adView
.getAdSize()
.getWidthInPixels(context);
int height = adView
.getAdSize()
.getHeightInPixels(context);
adView.measure(width, height);
adView.layout(left, top, left + width, top + height);
WritableMap payload = Arguments.createMap();
payload.putBoolean(RNFirebaseAdMobNativeExpress.Events.EVENT_AD_VIDEO_CONTENT.toString(), false);
payload.putBoolean(
RNFirebaseAdMobNativeExpress.Events.EVENT_AD_VIDEO_CONTENT.toString(),
false
);
payload.putInt("width", width);
payload.putInt("height", height);
@ -251,4 +235,24 @@ public class RNFirebaseAdMobBanner extends SimpleViewManager<ReactViewGroup> {
emitter.receiveEvent(viewGroup.getId(), BANNER_EVENT, event);
}
public enum Events {
EVENT_AD_SIZE_CHANGE("onSizeChange"),
EVENT_AD_LOADED("onAdLoaded"),
EVENT_AD_FAILED_TO_LOAD("onAdFailedToLoad"),
EVENT_AD_OPENED("onAdOpened"),
EVENT_AD_CLOSED("onAdClosed"),
EVENT_AD_LEFT_APPLICATION("onAdLeftApplication");
private final String event;
Events(final String name) {
event = name;
}
@Override
public String toString() {
return event;
}
}
}

View File

@ -25,38 +25,10 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
public static final String REACT_CLASS = "RNFirebaseAdMobNativeExpress";
public static final String BANNER_EVENT = "onBannerEvent";
public enum Events {
EVENT_AD_SIZE_CHANGE("onSizeChange"),
EVENT_AD_LOADED("onAdLoaded"),
EVENT_AD_FAILED_TO_LOAD("onAdFailedToLoad"),
EVENT_AD_OPENED("onAdOpened"),
EVENT_AD_CLOSED("onAdClosed"),
EVENT_AD_LEFT_APPLICATION("onAdLeftApplication"),
EVENT_AD_VIDEO_END("onVideoEnd"),
EVENT_AD_VIDEO_MUTE("onVideoMute"),
EVENT_AD_VIDEO_PAUSE("onVideoPause"),
EVENT_AD_VIDEO_PLAY("onVideoPlay"),
EVENT_AD_VIDEO_START("onVideoStart"),
EVENT_AD_VIDEO_CONTENT("hasVideoContent");
private final String event;
Events(final String name) {
event = name;
}
@Override
public String toString() {
return event;
}
}
private ThemedReactContext context;
private ReactViewGroup viewGroup;
private RCTEventEmitter emitter;
private Boolean requested = false;
// Internal prop values
private AdRequest.Builder request;
private VideoOptions.Builder videoOptions;
@ -70,6 +42,7 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
/**
* Create & return view instance
*
* @param themedReactContext
* @return
*/
@ -105,6 +78,7 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
/**
* Declare custom events
*
* @return
*/
@Override
@ -116,6 +90,7 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
/**
* Handle unitId prop
*
* @param view
* @param value
*/
@ -127,6 +102,7 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
/**
* Handle request prop
*
* @param view
* @param map
*/
@ -138,6 +114,7 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
/**
* Handle video prop
*
* @param view
* @param map
*/
@ -149,6 +126,7 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
/**
* Handle size prop
*
* @param view
* @param value
*/
@ -210,8 +188,12 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
int left = adView.getLeft();
int top = adView.getTop();
int width = adView.getAdSize().getWidthInPixels(context);
int height = adView.getAdSize().getHeightInPixels(context);
int width = adView
.getAdSize()
.getWidthInPixels(context);
int height = adView
.getAdSize()
.getHeightInPixels(context);
adView.measure(width, height);
adView.layout(left, top, left + width, top + height);
@ -230,17 +212,21 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
public void onVideoEnd() {
sendEvent(Events.EVENT_AD_VIDEO_END.toString(), null);
}
public void onVideoMute(boolean isMuted) {
WritableMap videoMutePayload = Arguments.createMap();
videoMutePayload.putBoolean("isMuted", isMuted);
sendEvent(Events.EVENT_AD_VIDEO_MUTE.toString(), videoMutePayload);
}
public void onVideoPause() {
sendEvent(Events.EVENT_AD_VIDEO_PAUSE.toString(), null);
}
public void onVideoPlay() {
sendEvent(Events.EVENT_AD_VIDEO_PLAY.toString(), null);
}
public void onVideoStart() {
sendEvent(Events.EVENT_AD_VIDEO_START.toString(), null);
}
@ -273,6 +259,7 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
/**
* Sends an event back to the JS component to handle
*
* @param type
* @param payload
*/
@ -287,4 +274,30 @@ public class RNFirebaseAdMobNativeExpress extends SimpleViewManager<ReactViewGro
int id = viewGroup.getId();
emitter.receiveEvent(viewGroup.getId(), BANNER_EVENT, event);
}
public enum Events {
EVENT_AD_SIZE_CHANGE("onSizeChange"),
EVENT_AD_LOADED("onAdLoaded"),
EVENT_AD_FAILED_TO_LOAD("onAdFailedToLoad"),
EVENT_AD_OPENED("onAdOpened"),
EVENT_AD_CLOSED("onAdClosed"),
EVENT_AD_LEFT_APPLICATION("onAdLeftApplication"),
EVENT_AD_VIDEO_END("onVideoEnd"),
EVENT_AD_VIDEO_MUTE("onVideoMute"),
EVENT_AD_VIDEO_PAUSE("onVideoPause"),
EVENT_AD_VIDEO_PLAY("onVideoPlay"),
EVENT_AD_VIDEO_START("onVideoStart"),
EVENT_AD_VIDEO_CONTENT("hasVideoContent");
private final String event;
Events(final String name) {
event = name;
}
@Override
public String toString() {
return event;
}
}
}

View File

@ -1,7 +1,6 @@
package io.invertase.firebase.admob;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.UIManagerModule;
@ -9,7 +8,6 @@ import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@SuppressWarnings("unused")

View File

@ -18,6 +18,7 @@ class RNFirebaseAdMobUtils {
/**
* Convert common AdMob errors into a standard format
*
* @param errorCode
* @return
*/
@ -27,11 +28,17 @@ class RNFirebaseAdMobUtils {
switch (errorCode) {
case AdRequest.ERROR_CODE_INTERNAL_ERROR:
map.putString("code", "admob/error-code-internal-error");
map.putString("message", "Something happened internally; for instance, an invalid response was received from the ad server.");
map.putString(
"message",
"Something happened internally; for instance, an invalid response was received from the ad server."
);
break;
case AdRequest.ERROR_CODE_INVALID_REQUEST:
map.putString("code", "admob/error-code-invalid-request");
map.putString("message", "The ad request was invalid; for instance, the ad unit ID was incorrect.");
map.putString(
"message",
"The ad request was invalid; for instance, the ad unit ID was incorrect."
);
break;
case AdRequest.ERROR_CODE_NETWORK_ERROR:
map.putString("code", "admob/error-code-network-error");
@ -39,7 +46,10 @@ class RNFirebaseAdMobUtils {
break;
case AdRequest.ERROR_CODE_NO_FILL:
map.putString("code", "admob/error-code-no-fill");
map.putString("message", "The ad request was successful, but no ad was returned due to lack of ad inventory.");
map.putString(
"message",
"The ad request was successful, but no ad was returned due to lack of ad inventory."
);
break;
}
@ -114,6 +124,7 @@ class RNFirebaseAdMobUtils {
/**
* Map the size prop to the AdSize
*
* @param value
* @return
*/

View File

@ -3,10 +3,8 @@ package io.invertase.firebase.admob;
import android.app.Activity;
import android.support.annotation.Nullable;
import android.util.Log;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.WritableMap;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
@ -60,6 +58,7 @@ class RNFirebaseAdmobInterstitial {
/**
* Load an Ad with a AdRequest instance
*
* @param adRequest
*/
void loadAd(final AdRequest adRequest) {
@ -93,6 +92,7 @@ class RNFirebaseAdmobInterstitial {
/**
* Send a native event over the bridge with a type and optional payload
*
* @param type
* @param payload
*/

View File

@ -1,15 +1,15 @@
package io.invertase.firebase.analytics;
import android.util.Log;
import android.app.Activity;
import android.support.annotation.Nullable;
import android.util.Log;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
public class RNFirebaseAnalytics extends ReactContextBaseJavaModule {
@ -31,7 +31,9 @@ public class RNFirebaseAnalytics extends ReactContextBaseJavaModule {
@ReactMethod
public void logEvent(final String name, @Nullable final ReadableMap params) {
FirebaseAnalytics.getInstance(getReactApplicationContext()).logEvent(name, Arguments.toBundle(params));
FirebaseAnalytics
.getInstance(getReactApplicationContext())
.logEvent(name, Arguments.toBundle(params));
}
/**
@ -39,7 +41,9 @@ public class RNFirebaseAnalytics extends ReactContextBaseJavaModule {
*/
@ReactMethod
public void setAnalyticsCollectionEnabled(final Boolean enabled) {
FirebaseAnalytics.getInstance(getReactApplicationContext()).setAnalyticsCollectionEnabled(enabled);
FirebaseAnalytics
.getInstance(getReactApplicationContext())
.setAnalyticsCollectionEnabled(enabled);
}
/**
@ -55,7 +59,9 @@ public class RNFirebaseAnalytics extends ReactContextBaseJavaModule {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
FirebaseAnalytics.getInstance(getReactApplicationContext()).setCurrentScreen(activity, screenName, screenClassOverride);
FirebaseAnalytics
.getInstance(getReactApplicationContext())
.setCurrentScreen(activity, screenName, screenClassOverride);
}
});
}
@ -66,7 +72,9 @@ public class RNFirebaseAnalytics extends ReactContextBaseJavaModule {
*/
@ReactMethod
public void setMinimumSessionDuration(final double milliseconds) {
FirebaseAnalytics.getInstance(getReactApplicationContext()).setMinimumSessionDuration((long) milliseconds);
FirebaseAnalytics
.getInstance(getReactApplicationContext())
.setMinimumSessionDuration((long) milliseconds);
}
/**
@ -74,7 +82,9 @@ public class RNFirebaseAnalytics extends ReactContextBaseJavaModule {
*/
@ReactMethod
public void setSessionTimeoutDuration(final double milliseconds) {
FirebaseAnalytics.getInstance(getReactApplicationContext()).setSessionTimeoutDuration((long) milliseconds);
FirebaseAnalytics
.getInstance(getReactApplicationContext())
.setSessionTimeoutDuration((long) milliseconds);
}
/**
@ -82,7 +92,9 @@ public class RNFirebaseAnalytics extends ReactContextBaseJavaModule {
*/
@ReactMethod
public void setUserId(final String id) {
FirebaseAnalytics.getInstance(getReactApplicationContext()).setUserId(id);
FirebaseAnalytics
.getInstance(getReactApplicationContext())
.setUserId(id);
}
/**
@ -91,6 +103,8 @@ public class RNFirebaseAnalytics extends ReactContextBaseJavaModule {
*/
@ReactMethod
public void setUserProperty(final String name, final String value) {
FirebaseAnalytics.getInstance(getReactApplicationContext()).setUserProperty(name, value);
FirebaseAnalytics
.getInstance(getReactApplicationContext())
.setUserProperty(name, value);
}
}

View File

@ -3,7 +3,6 @@ package io.invertase.firebase.analytics;
import android.support.annotation.RequiresPermission;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.UIManagerModule;

View File

@ -1,7 +1,6 @@
package io.invertase.firebase.auth;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.UIManagerModule;

View File

@ -3,26 +3,25 @@ package io.invertase.firebase.config;
import android.support.annotation.NonNull;
import android.util.Log;
import com.google.android.gms.tasks.Task;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableArray;
import com.google.android.gms.tasks.OnCompleteListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.google.firebase.FirebaseApp;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigFetchThrottledException;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.List;
import io.invertase.firebase.Utils;
@ -49,11 +48,14 @@ class RNFirebaseRemoteConfig extends ReactContextBaseJavaModule {
return TAG;
}
@ReactMethod public void enableDeveloperMode() {
@ReactMethod
public void enableDeveloperMode() {
FirebaseRemoteConfigSettings.Builder settings = new FirebaseRemoteConfigSettings.Builder();
settings.setDeveloperModeEnabled(true);
FirebaseRemoteConfig.getInstance().setConfigSettings(settings.build());
FirebaseRemoteConfig
.getInstance()
.setConfigSettings(settings.build());
}
@ReactMethod
@ -68,13 +70,19 @@ class RNFirebaseRemoteConfig extends ReactContextBaseJavaModule {
@ReactMethod
public void activateFetched(final Promise promise) {
Boolean status = FirebaseRemoteConfig.getInstance().activateFetched();
Boolean status = FirebaseRemoteConfig
.getInstance()
.activateFetched();
promise.resolve(status);
}
@ReactMethod
public void getValue(String key, final Promise promise) {
FirebaseRemoteConfigValue value = FirebaseRemoteConfig.getInstance().getValue(key);
FirebaseRemoteConfigValue value = FirebaseRemoteConfig
.getInstance()
.getValue(key);
promise.resolve(convertRemoteConfigValue(value));
}
@ -84,7 +92,10 @@ class RNFirebaseRemoteConfig extends ReactContextBaseJavaModule {
List<Object> keysList = Utils.recursivelyDeconstructReadableArray(keys);
for (Object key : keysList) {
FirebaseRemoteConfigValue value = FirebaseRemoteConfig.getInstance().getValue((String) key);
FirebaseRemoteConfigValue value = FirebaseRemoteConfig
.getInstance()
.getValue((String) key);
array.pushMap(convertRemoteConfigValue(value));
}
@ -93,7 +104,10 @@ class RNFirebaseRemoteConfig extends ReactContextBaseJavaModule {
@ReactMethod
public void getKeysByPrefix(String prefix, final Promise promise) {
Set<String> keys = FirebaseRemoteConfig.getInstance().getKeysByPrefix(prefix);
Set<String> keys = FirebaseRemoteConfig
.getInstance()
.getKeysByPrefix(prefix);
WritableArray array = Arguments.createArray();
for (String key : keys) {
@ -106,16 +120,26 @@ class RNFirebaseRemoteConfig extends ReactContextBaseJavaModule {
@ReactMethod
public void setDefaults(ReadableMap map) {
Map<String, Object> convertedMap = Utils.recursivelyDeconstructReadableMap(map);
FirebaseRemoteConfig.getInstance().setDefaults(convertedMap);
FirebaseRemoteConfig
.getInstance()
.setDefaults(convertedMap);
}
@ReactMethod
public void setDefaultsFromResource(int resourceId) {
FirebaseRemoteConfig.getInstance().setDefaults(resourceId);
FirebaseRemoteConfig
.getInstance()
.setDefaults(resourceId);
}
private void fetchInternal(final Promise promise, Boolean withExpiration, long expirationDuration) {
FirebaseRemoteConfig.getInstance().fetch(withExpiration ? expirationDuration : 43200) // 12 hours default
private void fetchInternal(
final Promise promise,
Boolean withExpiration,
long expirationDuration
) {
FirebaseRemoteConfig
.getInstance()
.fetch(withExpiration ? expirationDuration : 43200) // 12 hours default
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
@ -123,9 +147,17 @@ class RNFirebaseRemoteConfig extends ReactContextBaseJavaModule {
promise.resolve(null);
} else {
if (task.getException() instanceof FirebaseRemoteConfigFetchThrottledException) {
promise.reject("config/throttled", "fetch() operation cannot be completed successfully, due to throttling.", task.getException());
promise.reject(
"config/throttled",
"fetch() operation cannot be completed successfully, due to throttling.",
task.getException()
);
} else {
promise.reject("config/failure", "fetch() operation cannot be completed successfully.", task.getException());
promise.reject(
"config/failure",
"fetch() operation cannot be completed successfully.",
task.getException()
);
}
}
}

View File

@ -1,7 +1,6 @@
package io.invertase.firebase.config;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.UIManagerModule;

View File

@ -3,10 +3,9 @@ package io.invertase.firebase.crash;
import android.util.Log;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.google.firebase.crash.FirebaseCrash;

View File

@ -1,7 +1,6 @@
package io.invertase.firebase.crash;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.UIManagerModule;

View File

@ -4,26 +4,25 @@ import android.os.AsyncTask;
import android.util.Log;
import android.util.SparseArray;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.google.firebase.FirebaseApp;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseException;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Logger;
import com.google.firebase.database.MutableData;
import com.google.firebase.database.OnDisconnect;
import com.google.firebase.database.ServerValue;
import com.google.firebase.database.Transaction;
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 java.util.HashMap;
import java.util.List;
@ -32,12 +31,11 @@ import java.util.Map;
import io.invertase.firebase.ErrorUtils;
import io.invertase.firebase.Utils;
public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
private static final String TAG = "RNFirebaseDatabase";
private static boolean enableLogging = false;
private HashMap<String, RNFirebaseDatabaseReference> references = new HashMap<>();
private static HashMap<String, Boolean> loggingLevelSet = new HashMap<>();
private HashMap<String, RNFirebaseDatabaseReference> references = new HashMap<>();
private SparseArray<RNFirebaseTransactionHandler> transactionHandlers = new SparseArray<>();
RNFirebaseDatabase(ReactApplicationContext reactContext) {
@ -49,6 +47,210 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* REACT NATIVE METHODS
*/
/**
* Resolve null or reject with a js like error if databaseError exists
*
* @param promise
* @param databaseError
*/
static void handlePromise(Promise promise, DatabaseError databaseError) {
if (databaseError != null) {
WritableMap jsError = getJSError(databaseError);
promise.reject(
jsError.getString("code"),
jsError.getString("message"),
databaseError.toException()
);
} else {
promise.resolve(null);
}
}
/**
* Get a database instance for a specific firebase app instance
*
* @param appName
* @param dbURL
* @return
*/
public static FirebaseDatabase getDatabaseForApp(String appName, String dbURL) {
FirebaseDatabase firebaseDatabase;
if (dbURL != null && dbURL.length() > 0) {
if (appName != null && appName.length() > 0) {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
firebaseDatabase = FirebaseDatabase.getInstance(firebaseApp, dbURL);
} else {
firebaseDatabase = FirebaseDatabase.getInstance(dbURL);
}
} else {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
firebaseDatabase = FirebaseDatabase.getInstance(firebaseApp);
}
Boolean logLevel = loggingLevelSet.get(firebaseDatabase
.getApp()
.getName());
if (enableLogging && (logLevel == null || !logLevel)) {
try {
loggingLevelSet.put(firebaseDatabase
.getApp()
.getName(), enableLogging);
firebaseDatabase.setLogLevel(Logger.Level.DEBUG);
} catch (DatabaseException dex) {
// do nothing - to catch 'calls to setLogLevel must be made for use of database' errors
// only occurs in dev after reloading or if user has actually incorrectly called it.
Log.w(
TAG,
"WARNING: enableLogging(bool) must be called before any other use of database(). \n" +
"If you are sure you've done this then this message can be ignored during development as \n" +
"RN reloads can cause false positives. APP: " + firebaseDatabase
.getApp()
.getName()
);
}
} else if (!enableLogging && (logLevel != null && logLevel)) {
try {
loggingLevelSet.put(firebaseDatabase
.getApp()
.getName(), enableLogging);
firebaseDatabase.setLogLevel(Logger.Level.WARN);
} catch (DatabaseException dex) {
// do nothing - to catch 'calls to setLogLevel must be made for use of database' errors
// only occurs in dev after reloading or if user has actually incorrectly called it.
Log.w(
TAG,
"WARNING: enableLogging(bool) must be called before any other use of database(). \n" +
"If you are sure you've done this then this message can be ignored during development as \n" +
"RN reloads can cause false positives. APP: " + firebaseDatabase
.getApp()
.getName()
);
}
}
return firebaseDatabase;
}
/**
* Convert as firebase DatabaseError instance into a writable map
* with the correct web-like error codes.
*
* @param nativeError
* @return
*/
static WritableMap getJSError(DatabaseError nativeError) {
WritableMap errorMap = Arguments.createMap();
errorMap.putInt("nativeErrorCode", nativeError.getCode());
errorMap.putString("nativeErrorMessage", nativeError.getMessage());
String code;
String message;
String service = "Database";
switch (nativeError.getCode()) {
case DatabaseError.DATA_STALE:
code = ErrorUtils.getCodeWithService(service, "data-stale");
message = ErrorUtils.getMessageWithService(
"The transaction needs to be run again with current data.",
service,
code
);
break;
case DatabaseError.OPERATION_FAILED:
code = ErrorUtils.getCodeWithService(service, "failure");
message = ErrorUtils.getMessageWithService(
"The server indicated that this operation failed.",
service,
code
);
break;
case DatabaseError.PERMISSION_DENIED:
code = ErrorUtils.getCodeWithService(service, "permission-denied");
message = ErrorUtils.getMessageWithService(
"Client doesn't have permission to access the desired data.",
service,
code
);
break;
case DatabaseError.DISCONNECTED:
code = ErrorUtils.getCodeWithService(service, "disconnected");
message = ErrorUtils.getMessageWithService(
"The operation had to be aborted due to a network disconnect.",
service,
code
);
break;
case DatabaseError.EXPIRED_TOKEN:
code = ErrorUtils.getCodeWithService(service, "expired-token");
message = ErrorUtils.getMessageWithService(
"The supplied auth token has expired.",
service,
code
);
break;
case DatabaseError.INVALID_TOKEN:
code = ErrorUtils.getCodeWithService(service, "invalid-token");
message = ErrorUtils.getMessageWithService(
"The supplied auth token was invalid.",
service,
code
);
break;
case DatabaseError.MAX_RETRIES:
code = ErrorUtils.getCodeWithService(service, "max-retries");
message = ErrorUtils.getMessageWithService(
"The transaction had too many retries.",
service,
code
);
break;
case DatabaseError.OVERRIDDEN_BY_SET:
code = ErrorUtils.getCodeWithService(service, "overridden-by-set");
message = ErrorUtils.getMessageWithService(
"The transaction was overridden by a subsequent set.",
service,
code
);
break;
case DatabaseError.UNAVAILABLE:
code = ErrorUtils.getCodeWithService(service, "unavailable");
message = ErrorUtils.getMessageWithService("The service is unavailable.", service, code);
break;
case DatabaseError.USER_CODE_EXCEPTION:
code = ErrorUtils.getCodeWithService(service, "user-code-exception");
message = ErrorUtils.getMessageWithService(
"User code called from the Firebase Database runloop threw an exception.",
service,
code
);
break;
case DatabaseError.NETWORK_ERROR:
code = ErrorUtils.getCodeWithService(service, "network-error");
message = ErrorUtils.getMessageWithService(
"The operation could not be performed due to a network error.",
service,
code
);
break;
case DatabaseError.WRITE_CANCELED:
code = ErrorUtils.getCodeWithService(service, "write-cancelled");
message = ErrorUtils.getMessageWithService(
"The write was canceled by the user.",
service,
code
);
break;
default:
code = ErrorUtils.getCodeWithService(service, "unknown");
message = ErrorUtils.getMessageWithService("An unknown error occurred.", service, code);
}
errorMap.putString("code", code);
errorMap.putString("message", message);
return errorMap;
}
/**
* @param appName
*/
@ -74,6 +276,11 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
getDatabaseForApp(appName, dbURL).setPersistenceEnabled(state);
}
/*
* TRANSACTIONS
*/
/**
* @param appName
* @param size
@ -83,7 +290,6 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
getDatabaseForApp(appName, dbURL).setPersistenceCacheSizeBytes((long) size);
}
/**
* @param enabled
*/
@ -95,42 +301,62 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
loggingLevelSet.put(app.getName(), enabled);
try {
if (enableLogging) {
FirebaseDatabase.getInstance(app).setLogLevel(Logger.Level.DEBUG);
FirebaseDatabase
.getInstance(app)
.setLogLevel(Logger.Level.DEBUG);
} else {
FirebaseDatabase.getInstance(app).setLogLevel(Logger.Level.WARN);
FirebaseDatabase
.getInstance(app)
.setLogLevel(Logger.Level.WARN);
}
} catch (DatabaseException dex) {
// do nothing - to catch 'calls to setLogLevel must be made for use of database' errors
// only occurs in dev after reloading or if user has actually incorrectly called it.
Log.w(TAG, "WARNING: enableLogging(bool) must be called before any other use of database(). \n" +
"If you are sure you've done this then this message can be ignored during development as \n" +
"RN reloads can cause false positives. APP: " + app.getName());
Log.w(
TAG,
"WARNING: enableLogging(bool) must be called before any other use of database(). \n" +
"If you are sure you've done this then this message can be ignored during development as \n" +
"RN reloads can cause false positives. APP: " + app.getName()
);
}
}
}
/*
* ON DISCONNECT
*/
/**
* @param appName
* @param path
* @param state
*/
@ReactMethod
public void keepSynced(String appName, String dbURL, String key, String path, ReadableArray modifiers, Boolean state) {
getInternalReferenceForApp(appName, dbURL, 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);
}
/*
* TRANSACTIONS
*/
/**
* @param transactionId
* @param updates
*/
@ReactMethod
public void transactionTryCommit(String appName, String dbURL, int transactionId, ReadableMap updates) {
public void transactionTryCommit(
String appName,
String dbURL,
int transactionId,
ReadableMap updates
) {
RNFirebaseTransactionHandler handler = transactionHandlers.get(transactionId);
if (handler != null) {
@ -147,7 +373,13 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param applyLocally
*/
@ReactMethod
public void transactionStart(final String appName, final String dbURL, 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() {
@ -156,7 +388,11 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
reference.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
final RNFirebaseTransactionHandler transactionHandler = new RNFirebaseTransactionHandler(transactionId, appName, dbURL);
final RNFirebaseTransactionHandler transactionHandler = new RNFirebaseTransactionHandler(
transactionId,
appName,
dbURL
);
transactionHandlers.put(transactionId, transactionHandler);
final WritableMap updatesMap = transactionHandler.createUpdateMap(mutableData);
@ -165,7 +401,11 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
Utils.sendEvent(getReactApplicationContext(), "database_transaction_event", updatesMap);
Utils.sendEvent(
getReactApplicationContext(),
"database_transaction_event",
updatesMap
);
}
});
@ -198,11 +438,6 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
});
}
/*
* ON DISCONNECT
*/
/**
* Set a value on a ref when the client disconnects from the firebase server.
*
@ -212,7 +447,13 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void onDisconnectSet(String appName, String dbURL, 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, dbURL, path);
@ -257,7 +498,13 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void onDisconnectUpdate(String appName, String dbURL, String path, ReadableMap props, final Promise promise) {
public void onDisconnectUpdate(
String appName,
String dbURL,
String path,
ReadableMap props,
final Promise promise
) {
DatabaseReference ref = getReferenceForAppPath(appName, dbURL, path);
OnDisconnect ondDisconnect = ref.onDisconnect();
@ -318,9 +565,17 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void set(String appName, String dbURL, String path, ReadableMap props, final Promise promise) {
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");
Object value = Utils
.recursivelyDeconstructReadableMap(props)
.get("value");
DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
@Override
@ -339,9 +594,17 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void setPriority(String appName, String dbURL, String path, ReadableMap priority, final Promise promise) {
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");
Object priorityValue = Utils
.recursivelyDeconstructReadableMap(priority)
.get("value");
DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
@Override
@ -361,10 +624,21 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void setWithPriority(String appName, String dbURL, String path, ReadableMap data, ReadableMap priority, final Promise promise) {
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");
Object dataValue = Utils
.recursivelyDeconstructReadableMap(data)
.get("value");
Object priorityValue = Utils
.recursivelyDeconstructReadableMap(priority)
.get("value");
DatabaseReference.CompletionListener listener = new DatabaseReference.CompletionListener() {
@Override
@ -383,7 +657,13 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void update(String appName, String dbURL, String path, ReadableMap props, final Promise promise) {
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);
@ -416,6 +696,9 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
ref.removeValue(listener);
}
/*
* INTERNALS/UTILS
*/
/**
* Subscribe once to a firebase reference.
@ -428,7 +711,15 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param promise
*/
@ReactMethod
public void once(String appName, String dbURL, String key, String path, ReadableArray modifiers, String eventType, Promise 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);
}
@ -466,80 +757,6 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
}
}
/*
* INTERNALS/UTILS
*/
/**
* Resolve null or reject with a js like error if databaseError exists
*
* @param promise
* @param databaseError
*/
static void handlePromise(Promise promise, DatabaseError databaseError) {
if (databaseError != null) {
WritableMap jsError = getJSError(databaseError);
promise.reject(
jsError.getString("code"),
jsError.getString("message"),
databaseError.toException()
);
} else {
promise.resolve(null);
}
}
/**
* Get a database instance for a specific firebase app instance
*
* @param appName
* @param dbURL
* @return
*/
public static FirebaseDatabase getDatabaseForApp(String appName, String dbURL) {
FirebaseDatabase firebaseDatabase;
if(dbURL != null && dbURL.length() > 0) {
if (appName != null && appName.length() > 0) {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
firebaseDatabase = FirebaseDatabase.getInstance(firebaseApp, dbURL);
} else {
firebaseDatabase = FirebaseDatabase.getInstance(dbURL);
}
} else {
FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
firebaseDatabase = FirebaseDatabase.getInstance(firebaseApp);
}
Boolean logLevel = loggingLevelSet.get(firebaseDatabase.getApp().getName());
if (enableLogging && (logLevel == null || !logLevel)) {
try {
loggingLevelSet.put(firebaseDatabase.getApp().getName(), enableLogging);
firebaseDatabase.setLogLevel(Logger.Level.DEBUG);
} catch (DatabaseException dex) {
// do nothing - to catch 'calls to setLogLevel must be made for use of database' errors
// only occurs in dev after reloading or if user has actually incorrectly called it.
Log.w(TAG, "WARNING: enableLogging(bool) must be called before any other use of database(). \n" +
"If you are sure you've done this then this message can be ignored during development as \n" +
"RN reloads can cause false positives. APP: " + firebaseDatabase.getApp().getName());
}
} else if (!enableLogging && (logLevel != null && logLevel)) {
try {
loggingLevelSet.put(firebaseDatabase.getApp().getName(), enableLogging);
firebaseDatabase.setLogLevel(Logger.Level.WARN);
} catch (DatabaseException dex) {
// do nothing - to catch 'calls to setLogLevel must be made for use of database' errors
// only occurs in dev after reloading or if user has actually incorrectly called it.
Log.w(TAG, "WARNING: enableLogging(bool) must be called before any other use of database(). \n" +
"If you are sure you've done this then this message can be ignored during development as \n" +
"RN reloads can cause false positives. APP: " + firebaseDatabase.getApp().getName());
}
}
return firebaseDatabase;
}
/**
* Get a database reference for a specific app and path
*
@ -560,7 +777,13 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param modifiers
* @return
*/
private RNFirebaseDatabaseReference getInternalReferenceForApp(String appName, String dbURL, String key, String path, ReadableArray modifiers) {
private RNFirebaseDatabaseReference getInternalReferenceForApp(
String appName,
String dbURL,
String key,
String path,
ReadableArray modifiers
) {
return new RNFirebaseDatabaseReference(
getReactApplicationContext(),
appName,
@ -578,7 +801,11 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
* @param props
* @return
*/
private RNFirebaseDatabaseReference getCachedInternalReferenceForApp(String appName, String dbURL, 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");
@ -593,81 +820,6 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
return existingRef;
}
/**
* Convert as firebase DatabaseError instance into a writable map
* with the correct web-like error codes.
*
* @param nativeError
* @return
*/
static WritableMap getJSError(DatabaseError nativeError) {
WritableMap errorMap = Arguments.createMap();
errorMap.putInt("nativeErrorCode", nativeError.getCode());
errorMap.putString("nativeErrorMessage", nativeError.getMessage());
String code;
String message;
String service = "Database";
switch (nativeError.getCode()) {
case DatabaseError.DATA_STALE:
code = ErrorUtils.getCodeWithService(service, "data-stale");
message = ErrorUtils.getMessageWithService("The transaction needs to be run again with current data.", service, code);
break;
case DatabaseError.OPERATION_FAILED:
code = ErrorUtils.getCodeWithService(service, "failure");
message = ErrorUtils.getMessageWithService("The server indicated that this operation failed.", service, code);
break;
case DatabaseError.PERMISSION_DENIED:
code = ErrorUtils.getCodeWithService(service, "permission-denied");
message = ErrorUtils.getMessageWithService("Client doesn't have permission to access the desired data.", service, code);
break;
case DatabaseError.DISCONNECTED:
code = ErrorUtils.getCodeWithService(service, "disconnected");
message = ErrorUtils.getMessageWithService("The operation had to be aborted due to a network disconnect.", service, code);
break;
case DatabaseError.EXPIRED_TOKEN:
code = ErrorUtils.getCodeWithService(service, "expired-token");
message = ErrorUtils.getMessageWithService("The supplied auth token has expired.", service, code);
break;
case DatabaseError.INVALID_TOKEN:
code = ErrorUtils.getCodeWithService(service, "invalid-token");
message = ErrorUtils.getMessageWithService("The supplied auth token was invalid.", service, code);
break;
case DatabaseError.MAX_RETRIES:
code = ErrorUtils.getCodeWithService(service, "max-retries");
message = ErrorUtils.getMessageWithService("The transaction had too many retries.", service, code);
break;
case DatabaseError.OVERRIDDEN_BY_SET:
code = ErrorUtils.getCodeWithService(service, "overridden-by-set");
message = ErrorUtils.getMessageWithService("The transaction was overridden by a subsequent set.", service, code);
break;
case DatabaseError.UNAVAILABLE:
code = ErrorUtils.getCodeWithService(service, "unavailable");
message = ErrorUtils.getMessageWithService("The service is unavailable.", service, code);
break;
case DatabaseError.USER_CODE_EXCEPTION:
code = ErrorUtils.getCodeWithService(service, "user-code-exception");
message = ErrorUtils.getMessageWithService("User code called from the Firebase Database runloop threw an exception.", service, code);
break;
case DatabaseError.NETWORK_ERROR:
code = ErrorUtils.getCodeWithService(service, "network-error");
message = ErrorUtils.getMessageWithService("The operation could not be performed due to a network error.", service, code);
break;
case DatabaseError.WRITE_CANCELED:
code = ErrorUtils.getCodeWithService(service, "write-cancelled");
message = ErrorUtils.getMessageWithService("The write was canceled by the user.", service, code);
break;
default:
code = ErrorUtils.getCodeWithService(service, "unknown");
message = ErrorUtils.getMessageWithService("An unknown error occurred.", service, code);
}
errorMap.putString("code", code);
errorMap.putString("message", message);
return errorMap;
}
/**
* React Method - returns this module name
*

View File

@ -1,7 +1,6 @@
package io.invertase.firebase.database;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.UIManagerModule;

View File

@ -1,82 +1,41 @@
package io.invertase.firebase.database;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.lang.ref.WeakReference;
import android.util.Log;
import android.os.AsyncTask;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.google.firebase.database.Query;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.invertase.firebase.Utils;
class RNFirebaseDatabaseReference {
private static final String TAG = "RNFirebaseDBReference";
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<>();
private HashMap<String, ValueEventListener> valueEventListeners = new HashMap<>();
/**
* AsyncTask to convert DataSnapshot instances to WritableMap instances.
*
* Introduced due to https://github.com/invertase/react-native-firebase/issues/1284
*/
private static class DataSnapshotToMapAsyncTask extends AsyncTask<Object, Void, WritableMap> {
private WeakReference<ReactContext> reactContextWeakReference;
private WeakReference<RNFirebaseDatabaseReference> referenceWeakReference;
DataSnapshotToMapAsyncTask(ReactContext context, RNFirebaseDatabaseReference reference) {
referenceWeakReference = new WeakReference<>(reference);
reactContextWeakReference = new WeakReference<>(context);
}
@Override
protected final WritableMap doInBackground(Object... params) {
DataSnapshot dataSnapshot = (DataSnapshot) params[0];
@Nullable String previousChildName = (String) params[1];
try {
return RNFirebaseDatabaseUtils.snapshotToMap(dataSnapshot, previousChildName);
} catch (RuntimeException e) {
if (isAvailable()) {
reactContextWeakReference.get().handleException(e);
}
throw e;
}
}
@Override
protected void onPostExecute(WritableMap writableMap) {
// do nothing as overridden on usage
}
Boolean isAvailable() {
return reactContextWeakReference.get() != null && referenceWeakReference.get() != null;
}
}
/**
* RNFirebase wrapper around FirebaseDatabaseReference,
* handles Query generation and event listeners.
@ -87,7 +46,14 @@ class RNFirebaseDatabaseReference {
* @param refPath
* @param modifiersArray
*/
RNFirebaseDatabaseReference(ReactContext context, String app, String url, 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;
@ -96,7 +62,6 @@ class RNFirebaseDatabaseReference {
buildDatabaseQueryAtPathAndModifiers(refPath, modifiersArray);
}
/**
* Used outside of class for keepSynced etc.
*
@ -113,7 +78,8 @@ class RNFirebaseDatabaseReference {
* @return
*/
private Boolean hasEventListener(String eventRegistrationKey) {
return valueEventListeners.containsKey(eventRegistrationKey) || childEventListeners.containsKey(eventRegistrationKey);
return valueEventListeners.containsKey(eventRegistrationKey) || childEventListeners.containsKey(
eventRegistrationKey);
}
/**
@ -155,7 +121,6 @@ class RNFirebaseDatabaseReference {
}
/**
* Add a ChildEventListener to the query and internally keep a reference to it.
*
@ -174,8 +139,10 @@ class RNFirebaseDatabaseReference {
* @param promise
*/
private void addOnceValueEventListener(final Promise promise) {
@SuppressLint("StaticFieldLeak")
final DataSnapshotToMapAsyncTask asyncTask = new DataSnapshotToMapAsyncTask(reactContext, this) {
@SuppressLint("StaticFieldLeak") final DataSnapshotToMapAsyncTask asyncTask = new DataSnapshotToMapAsyncTask(
reactContext,
this
) {
@Override
protected void onPostExecute(WritableMap writableMap) {
if (this.isAvailable()) promise.resolve(writableMap);
@ -252,7 +219,6 @@ class RNFirebaseDatabaseReference {
query.addChildEventListener(childEventListener);
}
/**
* Handles a React Native JS '.on(..)' request and initializes listeners.
*
@ -280,7 +246,6 @@ class RNFirebaseDatabaseReference {
}
}
/**
* Add a native .on('child_X',.. ) event listener.
*
@ -365,7 +330,12 @@ class RNFirebaseDatabaseReference {
* @param dataSnapshot
* @param previousChildName
*/
private void handleDatabaseEvent(final String eventType, final ReadableMap registration, DataSnapshot dataSnapshot, @Nullable String previousChildName) {
private void handleDatabaseEvent(
final String eventType,
final ReadableMap registration,
DataSnapshot dataSnapshot,
@Nullable String previousChildName
) {
@SuppressLint("StaticFieldLeak")
DataSnapshotToMapAsyncTask asyncTask = new DataSnapshotToMapAsyncTask(reactContext, this) {
@Override
@ -424,11 +394,6 @@ class RNFirebaseDatabaseReference {
}
}
/* =================
* QUERY MODIFIERS
* =================
*/
/**
* @param name
* @param type
@ -451,6 +416,11 @@ class RNFirebaseDatabaseReference {
}
}
/* =================
* QUERY MODIFIERS
* =================
*/
/**
* @param name
* @param type
@ -481,12 +451,6 @@ class RNFirebaseDatabaseReference {
}
}
/* ===============
* QUERY FILTERS
* ===============
*/
/**
* @param key
* @param valueType
@ -517,6 +481,12 @@ class RNFirebaseDatabaseReference {
}
}
/* ===============
* QUERY FILTERS
* ===============
*/
/**
* @param key
* @param valueType
@ -576,4 +546,46 @@ class RNFirebaseDatabaseReference {
}
}
}
/**
* AsyncTask to convert DataSnapshot instances to WritableMap instances.
* <p>
* Introduced due to https://github.com/invertase/react-native-firebase/issues/1284
*/
private static class DataSnapshotToMapAsyncTask extends AsyncTask<Object, Void, WritableMap> {
private WeakReference<ReactContext> reactContextWeakReference;
private WeakReference<RNFirebaseDatabaseReference> referenceWeakReference;
DataSnapshotToMapAsyncTask(ReactContext context, RNFirebaseDatabaseReference reference) {
referenceWeakReference = new WeakReference<>(reference);
reactContextWeakReference = new WeakReference<>(context);
}
@Override
protected final WritableMap doInBackground(Object... params) {
DataSnapshot dataSnapshot = (DataSnapshot) params[0];
@Nullable String previousChildName = (String) params[1];
try {
return RNFirebaseDatabaseUtils.snapshotToMap(dataSnapshot, previousChildName);
} catch (RuntimeException e) {
if (isAvailable()) {
reactContextWeakReference
.get()
.handleException(e);
}
throw e;
}
}
@Override
protected void onPostExecute(WritableMap writableMap) {
// do nothing as overridden on usage
}
Boolean isAvailable() {
return reactContextWeakReference.get() != null && referenceWeakReference.get() != null;
}
}
}

View File

@ -20,7 +20,10 @@ public class RNFirebaseDatabaseUtils {
* @param previousChildName
* @return
*/
public static WritableMap snapshotToMap(DataSnapshot dataSnapshot, @Nullable String previousChildName) {
public static WritableMap snapshotToMap(
DataSnapshot dataSnapshot,
@Nullable String previousChildName
) {
WritableMap result = Arguments.createMap();
WritableMap snapshot = snapshotToMap(dataSnapshot);
@ -71,7 +74,10 @@ public class RNFirebaseDatabaseUtils {
}
} else {
if (snapshot.getValue() != null) {
String type = snapshot.getValue().getClass().getName();
String type = snapshot
.getValue()
.getClass()
.getName();
switch (type) {
case "java.lang.Boolean":
case "java.lang.Long":
@ -101,7 +107,10 @@ public class RNFirebaseDatabaseUtils {
}
} else {
if (mutableData.getValue() != null) {
String type = mutableData.getValue().getClass().getName();
String type = mutableData
.getValue()
.getClass()
.getName();
switch (type) {
case "java.lang.Boolean":
case "java.lang.Long":
@ -190,7 +199,9 @@ public class RNFirebaseDatabaseUtils {
expectedKey = key;
}
Any castedChild = castValue(child);
switch (castedChild.getClass().getName()) {
switch (castedChild
.getClass()
.getName()) {
case "java.lang.Boolean":
array.pushBoolean((Boolean) castedChild);
break;
@ -211,7 +222,12 @@ public class RNFirebaseDatabaseUtils {
array.pushArray((WritableArray) castedChild);
break;
default:
Log.w(TAG, "Invalid type: " + castedChild.getClass().getName());
Log.w(
TAG,
"Invalid type: " + castedChild
.getClass()
.getName()
);
break;
}
expectedKey++;
@ -236,7 +252,9 @@ public class RNFirebaseDatabaseUtils {
expectedKey = key;
}
Any castedChild = castValue(child);
switch (castedChild.getClass().getName()) {
switch (castedChild
.getClass()
.getName()) {
case "java.lang.Boolean":
array.pushBoolean((Boolean) castedChild);
break;
@ -257,7 +275,12 @@ public class RNFirebaseDatabaseUtils {
array.pushArray((WritableArray) castedChild);
break;
default:
Log.w(TAG, "Invalid type: " + castedChild.getClass().getName());
Log.w(
TAG,
"Invalid type: " + castedChild
.getClass()
.getName()
);
break;
}
expectedKey++;
@ -275,7 +298,9 @@ public class RNFirebaseDatabaseUtils {
for (DataSnapshot child : snapshot.getChildren()) {
Any castedChild = castValue(child);
switch (castedChild.getClass().getName()) {
switch (castedChild
.getClass()
.getName()) {
case "java.lang.Boolean":
map.putBoolean(child.getKey(), (Boolean) castedChild);
break;
@ -295,7 +320,12 @@ public class RNFirebaseDatabaseUtils {
map.putArray(child.getKey(), (WritableArray) castedChild);
break;
default:
Log.w(TAG, "Invalid type: " + castedChild.getClass().getName());
Log.w(
TAG,
"Invalid type: " + castedChild
.getClass()
.getName()
);
break;
}
}
@ -312,7 +342,9 @@ public class RNFirebaseDatabaseUtils {
for (MutableData child : mutableData.getChildren()) {
Any castedChild = castValue(child);
switch (castedChild.getClass().getName()) {
switch (castedChild
.getClass()
.getName()) {
case "java.lang.Boolean":
map.putBoolean(child.getKey(), (Boolean) castedChild);
break;
@ -332,7 +364,12 @@ public class RNFirebaseDatabaseUtils {
map.putArray(child.getKey(), (WritableArray) castedChild);
break;
default:
Log.w(TAG, "Invalid type: " + castedChild.getClass().getName());
Log.w(
TAG,
"Invalid type: " + castedChild
.getClass()
.getName()
);
break;
}
}

View File

@ -19,18 +19,17 @@ import javax.annotation.Nullable;
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;
private boolean signalled;
public Object value;
boolean interrupted;
boolean abort = false;
boolean timeout = false;
private int transactionId;
private String appName;
private String dbURL;
private Map<String, Object> data;
private boolean signalled;
RNFirebaseTransactionHandler(int id, String app, String url) {
appName = app;
@ -127,7 +126,11 @@ public class RNFirebaseTransactionHandler {
}
WritableMap createResultMap(@Nullable DatabaseError error, boolean committed, DataSnapshot snapshot) {
WritableMap createResultMap(
@Nullable DatabaseError error,
boolean committed,
DataSnapshot snapshot
) {
WritableMap resultMap = Arguments.createMap();
resultMap.putInt("id", transactionId);
@ -144,7 +147,10 @@ public class RNFirebaseTransactionHandler {
if (error == null && timeout) {
WritableMap timeoutError = Arguments.createMap();
timeoutError.putString("code", "DATABASE/INTERNAL-TIMEOUT");
timeoutError.putString("message", "A timeout occurred whilst waiting for RN JS thread to send transaction updates.");
timeoutError.putString(
"message",
"A timeout occurred whilst waiting for RN JS thread to send transaction updates."
);
resultMap.putMap("error", timeoutError);
}
} else {

View File

@ -2,11 +2,10 @@ package io.invertase.firebase.fabric.crashlytics;
import android.util.Log;
import com.facebook.react.bridge.ReactMethod;
import com.crashlytics.android.Crashlytics;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.crashlytics.android.Crashlytics;
import com.facebook.react.bridge.ReactMethod;
public class RNFirebaseCrashlytics extends ReactContextBaseJavaModule {
@ -25,7 +24,9 @@ public class RNFirebaseCrashlytics extends ReactContextBaseJavaModule {
@ReactMethod
public void crash() {
Crashlytics.getInstance().crash();
Crashlytics
.getInstance()
.crash();
}
@ReactMethod

View File

@ -1,7 +1,6 @@
package io.invertase.firebase.fabric.crashlytics;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.UIManagerModule;

View File

@ -28,7 +28,9 @@ class DocumentSnapshotSerializeAsyncTask extends AsyncTask<Object, Void, Writabl
return FirestoreSerialize.snapshotToWritableMap(querySnapshot);
} catch (RuntimeException e) {
if (isAvailable()) {
reactContextWeakReference.get().handleException(e);
reactContextWeakReference
.get()
.handleException(e);
} else {
throw e;
}

View File

@ -48,15 +48,30 @@ public class FirestoreSerialize {
static WritableMap snapshotToWritableMap(DocumentSnapshot documentSnapshot) {
WritableMap documentMap = Arguments.createMap();
documentMap.putString(KEY_PATH, documentSnapshot.getReference().getPath());
documentMap.putString(
KEY_PATH,
documentSnapshot
.getReference()
.getPath()
);
if (documentSnapshot.exists()) {
documentMap.putMap(KEY_DATA, objectMapToWritable(documentSnapshot.getData()));
}
// metadata
WritableMap metadata = Arguments.createMap();
metadata.putBoolean("fromCache", documentSnapshot.getMetadata().isFromCache());
metadata.putBoolean("hasPendingWrites", documentSnapshot.getMetadata().hasPendingWrites());
metadata.putBoolean(
"fromCache",
documentSnapshot
.getMetadata()
.isFromCache()
);
metadata.putBoolean(
"hasPendingWrites",
documentSnapshot
.getMetadata()
.hasPendingWrites()
);
documentMap.putMap(KEY_METADATA, metadata);
return documentMap;
}
@ -77,8 +92,18 @@ public class FirestoreSerialize {
// metadata
WritableMap metadata = Arguments.createMap();
metadata.putBoolean("fromCache", querySnapshot.getMetadata().isFromCache());
metadata.putBoolean("hasPendingWrites", querySnapshot.getMetadata().hasPendingWrites());
metadata.putBoolean(
"fromCache",
querySnapshot
.getMetadata()
.isFromCache()
);
metadata.putBoolean(
"hasPendingWrites",
querySnapshot
.getMetadata()
.hasPendingWrites()
);
queryMap.putMap(KEY_METADATA, metadata);
return queryMap;

View File

@ -28,7 +28,9 @@ class QuerySnapshotSerializeAsyncTask extends AsyncTask<Object, Void, WritableMa
return FirestoreSerialize.snapshotToWritableMap(querySnapshot);
} catch (RuntimeException e) {
if (isAvailable()) {
reactContextWeakReference.get().handleException(e);
reactContextWeakReference
.get()
.handleException(e);
} else {
throw e;
}

View File

@ -34,7 +34,6 @@ import java.util.Map;
import io.invertase.firebase.ErrorUtils;
import io.invertase.firebase.Utils;
public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
private static final String TAG = "RNFirebaseFirestore";
private SparseArray<RNFirebaseFirestoreTransactionHandler> transactionHandlers = new SparseArray<>();
@ -83,7 +82,12 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
*/
static WritableMap getJSError(FirebaseFirestoreException nativeException) {
WritableMap errorMap = Arguments.createMap();
errorMap.putInt("nativeErrorCode", nativeException.getCode().value());
errorMap.putInt(
"nativeErrorCode",
nativeException
.getCode()
.value()
);
errorMap.putString("nativeErrorMessage", nativeException.getMessage());
String code;
@ -228,21 +232,23 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
@ReactMethod
public void disableNetwork(String appName, final Promise promise) {
getFirestoreForApp(appName).disableNetwork().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "disableNetwork:onComplete:success");
promise.resolve(null);
} else {
Log.e(TAG, "disableNetwork:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
getFirestoreForApp(appName)
.disableNetwork()
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "disableNetwork:onComplete:success");
promise.resolve(null);
} else {
Log.e(TAG, "disableNetwork:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
}
}
}
});
});
}
@ReactMethod
@ -256,21 +262,23 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
@ReactMethod
public void enableNetwork(String appName, final Promise promise) {
getFirestoreForApp(appName).enableNetwork().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "enableNetwork:onComplete:success");
promise.resolve(null);
} else {
Log.e(TAG, "enableNetwork:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
getFirestoreForApp(appName)
.enableNetwork()
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "enableNetwork:onComplete:success");
promise.resolve(null);
} else {
Log.e(TAG, "enableNetwork:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
}
}
}
});
});
}
@ReactMethod
@ -314,8 +322,10 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
}
@ReactMethod
public void documentBatch(final String appName, final ReadableArray writes,
final Promise promise) {
public void documentBatch(
final String appName, final ReadableArray writes,
final Promise promise
) {
FirebaseFirestore firestore = getFirestoreForApp(appName);
WriteBatch batch = firestore.batch();
final List<Object> writesArray = FirestoreSerialize.parseDocumentBatches(firestore, writes);
@ -346,18 +356,23 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
}
}
batch.commit().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "documentBatch:onComplete:success");
promise.resolve(null);
} else {
Log.e(TAG, "documentBatch:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(promise, (FirebaseFirestoreException) task.getException());
batch
.commit()
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "documentBatch:onComplete:success");
promise.resolve(null);
} else {
Log.e(TAG, "documentBatch:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
}
}
}
});
});
}
@ReactMethod
@ -421,17 +436,23 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
if (settings.hasKey("host")) {
firestoreSettings.setHost(settings.getString("host"));
} else {
firestoreSettings.setHost(firestore.getFirestoreSettings().getHost());
firestoreSettings.setHost(firestore
.getFirestoreSettings()
.getHost());
}
if (settings.hasKey("persistence")) {
firestoreSettings.setPersistenceEnabled(settings.getBoolean("persistence"));
} else {
firestoreSettings.setPersistenceEnabled(firestore.getFirestoreSettings().isPersistenceEnabled());
firestoreSettings.setPersistenceEnabled(firestore
.getFirestoreSettings()
.isPersistenceEnabled());
}
if (settings.hasKey("ssl")) {
firestoreSettings.setSslEnabled(settings.getBoolean("ssl"));
} else {
firestoreSettings.setSslEnabled(firestore.getFirestoreSettings().isSslEnabled());
firestoreSettings.setSslEnabled(firestore
.getFirestoreSettings()
.isSslEnabled());
}
// if (settings.hasKey("timestampsInSnapshots")) {
@ -731,8 +752,18 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule {
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put("deleteFieldValue", FieldValue.delete().toString());
constants.put("serverTimestampFieldValue", FieldValue.serverTimestamp().toString());
constants.put(
"deleteFieldValue",
FieldValue
.delete()
.toString()
);
constants.put(
"serverTimestampFieldValue",
FieldValue
.serverTimestamp()
.toString()
);
return constants;
}
}

View File

@ -89,21 +89,23 @@ class RNFirebaseFirestoreCollectionReference {
}
};
query.get(source).addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
Log.d(TAG, "get:onComplete:success");
serializeAsyncTask.execute(task.getResult());
} else {
Log.e(TAG, "get:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
query
.get(source)
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
Log.d(TAG, "get:onComplete:success");
serializeAsyncTask.execute(task.getResult());
} else {
Log.e(TAG, "get:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
}
}
}
});
});
}
void onSnapshot(final String listenerId, final ReadableMap queryListenOptions) {

View File

@ -39,7 +39,9 @@ public class RNFirebaseFirestoreDocumentReference {
this.path = path;
this.appName = appName;
this.reactContext = reactContext;
this.ref = RNFirebaseFirestore.getFirestoreForApp(appName).document(path);
this.ref = RNFirebaseFirestore
.getFirestoreForApp(appName)
.document(path);
}
static void offSnapshot(final String listenerId) {
@ -50,21 +52,23 @@ public class RNFirebaseFirestoreDocumentReference {
}
void delete(final Promise promise) {
this.ref.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "delete:onComplete:success");
promise.resolve(null);
} else {
Log.e(TAG, "delete:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
this.ref
.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "delete:onComplete:success");
promise.resolve(null);
} else {
Log.e(TAG, "delete:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
}
}
}
});
});
}
void get(final ReadableMap getOptions, final Promise promise) {
@ -92,21 +96,23 @@ public class RNFirebaseFirestoreDocumentReference {
}
};
this.ref.get(source).addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
Log.d(TAG, "get:onComplete:success");
serializeAsyncTask.execute(task.getResult());
} else {
Log.e(TAG, "get:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
this.ref
.get(source)
.addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
Log.d(TAG, "get:onComplete:success");
serializeAsyncTask.execute(task.getResult());
} else {
Log.e(TAG, "get:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
}
}
}
});
});
}
void onSnapshot(final String listenerId, final ReadableMap docListenOptions) {
@ -187,21 +193,23 @@ public class RNFirebaseFirestoreDocumentReference {
data
);
this.ref.update(map).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "update:onComplete:success");
promise.resolve(null);
} else {
Log.e(TAG, "update:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
this.ref
.update(map)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "update:onComplete:success");
promise.resolve(null);
} else {
Log.e(TAG, "update:onComplete:failure", task.getException());
RNFirebaseFirestore.promiseRejectException(
promise,
(FirebaseFirestoreException) task.getException()
);
}
}
}
});
});
}
/*

View File

@ -41,7 +41,10 @@ public class RNFirebaseFunctions extends ReactContextBaseJavaModule {
@ReactMethod
public void httpsCallable(final String name, ReadableMap wrapper, final Promise promise) {
Object input = wrapper.toHashMap().get(DATA_KEY);
Object input = wrapper
.toHashMap()
.get(DATA_KEY);
Log.d(TAG, "function:call:input:" + name + ":" + (input != null ? input.toString() : "null"));
HttpsCallableReference httpsCallableReference = FirebaseFunctions
@ -60,10 +63,14 @@ public class RNFirebaseFunctions extends ReactContextBaseJavaModule {
TAG,
"function:call:onSuccess:" + name
);
Log.d(
TAG,
"function:call:onSuccess:result:type:" + name + ":" + (result != null ? result.getClass().getName() : "null")
"function:call:onSuccess:result:type:" + name + ":" + (result != null ? result
.getClass()
.getName() : "null")
);
Log.d(
TAG,
"function:call:onSuccess:result:data:" + name + ":" + (result != null ? result.toString() : "null")
@ -71,7 +78,6 @@ public class RNFirebaseFunctions extends ReactContextBaseJavaModule {
Utils.mapPutValue(DATA_KEY, result, map);
promise.resolve(map);
}
})
.addOnFailureListener(new OnFailureListener() {
@ -87,7 +93,9 @@ public class RNFirebaseFunctions extends ReactContextBaseJavaModule {
if (exception instanceof FirebaseFunctionsException) {
FirebaseFunctionsException ffe = (FirebaseFunctionsException) exception;
details = ffe.getDetails();
code = ffe.getCode().name();
code = ffe
.getCode()
.name();
message = ffe.getLocalizedMessage();
} else {
message = exception.getLocalizedMessage();

View File

@ -1,8 +1,6 @@
package io.invertase.firebase.instanceid;
import java.io.IOException;
import android.util.Log;
import com.facebook.react.bridge.Promise;
@ -28,10 +26,12 @@ public class RNFirebaseInstanceId extends ReactContextBaseJavaModule {
}
@ReactMethod
public void delete(Promise promise){
public void delete(Promise promise) {
try {
Log.d(TAG, "Deleting instance id");
FirebaseInstanceId.getInstance().deleteInstanceId();
FirebaseInstanceId
.getInstance()
.deleteInstanceId();
promise.resolve(null);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
@ -40,15 +40,19 @@ public class RNFirebaseInstanceId extends ReactContextBaseJavaModule {
}
@ReactMethod
public void get(Promise promise){
String id = FirebaseInstanceId.getInstance().getId();
public void get(Promise promise) {
String id = FirebaseInstanceId
.getInstance()
.getId();
promise.resolve(id);
}
@ReactMethod
public void getToken(String authorizedEntity, String scope, Promise promise) {
try {
String token = FirebaseInstanceId.getInstance().getToken(authorizedEntity, scope);
String token = FirebaseInstanceId
.getInstance()
.getToken(authorizedEntity, scope);
Log.d(TAG, "Firebase token for " + authorizedEntity + ": " + token);
promise.resolve(token);
} catch (IOException e) {
@ -59,7 +63,9 @@ public class RNFirebaseInstanceId extends ReactContextBaseJavaModule {
@ReactMethod
public void deleteToken(String authorizedEntity, String scope, Promise promise) {
try {
FirebaseInstanceId.getInstance().deleteToken(authorizedEntity, scope);
FirebaseInstanceId
.getInstance()
.deleteToken(authorizedEntity, scope);
Log.d(TAG, "Firebase token deleted for " + authorizedEntity);
promise.resolve(null);
} catch (IOException e) {

View File

@ -28,7 +28,6 @@ import java.util.HashMap;
import java.util.Map;
import io.invertase.firebase.Utils;
import io.invertase.firebase.links.RNFirebaseLinks;
public class RNFirebaseInvites extends ReactContextBaseJavaModule implements ActivityEventListener, LifecycleEventListener {
private static final String TAG = "RNFirebaseInvites";
@ -58,21 +57,28 @@ public class RNFirebaseInvites extends ReactContextBaseJavaModule implements Act
}
} else {
if (getCurrentActivity() != null) {
FirebaseDynamicLinks.getInstance()
FirebaseDynamicLinks
.getInstance()
.getDynamicLink(getCurrentActivity().getIntent())
.addOnSuccessListener(new OnSuccessListener<PendingDynamicLinkData>() {
@Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
if (pendingDynamicLinkData != null) {
FirebaseAppInvite invite = FirebaseAppInvite.getInvitation(pendingDynamicLinkData);
FirebaseAppInvite invite = FirebaseAppInvite.getInvitation(
pendingDynamicLinkData);
if (invite == null) {
promise.resolve(null);
return;
}
mInitialDeepLink = pendingDynamicLinkData.getLink().toString();
mInitialDeepLink = pendingDynamicLinkData
.getLink()
.toString();
mInitialInvitationId = invite.getInvitationId();
promise.resolve(buildInvitationMap(mInitialDeepLink, mInitialInvitationId));
promise.resolve(buildInvitationMap(
mInitialDeepLink,
mInitialInvitationId
));
} else {
promise.resolve(null);
}
@ -83,7 +89,11 @@ public class RNFirebaseInvites extends ReactContextBaseJavaModule implements Act
@Override
public void onFailure(@NonNull Exception e) {
Log.e(TAG, "getInitialInvitation: failed to resolve invitation", e);
promise.reject("invites/initial-invitation-error", e.getMessage(), e);
promise.reject(
"invites/initial-invitation-error",
e.getMessage(),
e
);
}
});
} else {
@ -96,15 +106,22 @@ public class RNFirebaseInvites extends ReactContextBaseJavaModule implements Act
@ReactMethod
public void sendInvitation(ReadableMap invitationMap, Promise promise) {
if (!invitationMap.hasKey("message")) {
promise.reject("invites/invalid-invitation", "The supplied invitation is missing a 'message' field");
promise.reject(
"invites/invalid-invitation",
"The supplied invitation is missing a 'message' field"
);
return;
}
if (!invitationMap.hasKey("title")) {
promise.reject("invites/invalid-invitation", "The supplied invitation is missing a 'title' field");
promise.reject(
"invites/invalid-invitation",
"The supplied invitation is missing a 'title' field"
);
return;
}
AppInviteInvitation.IntentBuilder ib = new AppInviteInvitation.IntentBuilder(invitationMap.getString("title"));
AppInviteInvitation.IntentBuilder ib = new AppInviteInvitation.IntentBuilder(invitationMap.getString(
"title"));
if (invitationMap.hasKey("androidMinimumVersionCode")) {
Double androidMinimumVersionCode = invitationMap.getDouble("androidMinimumVersionCode");
ib = ib.setAndroidMinimumVersionCode(androidMinimumVersionCode.intValue());
@ -121,7 +138,8 @@ public class RNFirebaseInvites extends ReactContextBaseJavaModule implements Act
if (invitationMap.hasKey("iosClientId")) {
ib = ib.setOtherPlatformsTargetApplication(
AppInviteInvitation.IntentBuilder.PlatformMode.PROJECT_PLATFORM_IOS,
invitationMap.getString("iosClientId"));
invitationMap.getString("iosClientId")
);
}
ib = ib.setMessage(invitationMap.getString("message"));
@ -155,7 +173,9 @@ public class RNFirebaseInvites extends ReactContextBaseJavaModule implements Act
this.mPromise = promise;
// Start the intent
this.getCurrentActivity().startActivityForResult(invitationIntent, REQUEST_INVITE);
this
.getCurrentActivity()
.startActivityForResult(invitationIntent, REQUEST_INVITE);
}
//////////////////////////////////////////////////////////////////////
@ -179,22 +199,33 @@ public class RNFirebaseInvites extends ReactContextBaseJavaModule implements Act
@Override
public void onNewIntent(Intent intent) {
FirebaseDynamicLinks.getInstance()
FirebaseDynamicLinks
.getInstance()
.getDynamicLink(intent)
.addOnSuccessListener(new OnSuccessListener<PendingDynamicLinkData>() {
@Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
if (pendingDynamicLinkData != null) {
FirebaseAppInvite invite = FirebaseAppInvite.getInvitation(pendingDynamicLinkData);
FirebaseAppInvite invite = FirebaseAppInvite.getInvitation(
pendingDynamicLinkData);
if (invite == null) {
// this is a dynamic link, not an invitation
return;
}
String deepLink = pendingDynamicLinkData.getLink().toString();
String deepLink = pendingDynamicLinkData
.getLink()
.toString();
String invitationId = invite.getInvitationId();
WritableMap invitationMap = buildInvitationMap(deepLink, invitationId);
Utils.sendEvent(getReactApplicationContext(), "invites_invitation_received", invitationMap);
WritableMap invitationMap = buildInvitationMap(
deepLink,
invitationId
);
Utils.sendEvent(
getReactApplicationContext(),
"invites_invitation_received",
invitationMap
);
}
}
});

View File

@ -13,17 +13,15 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.appinvite.FirebaseAppInvite;
import com.google.firebase.dynamiclinks.DynamicLink;
import com.google.firebase.dynamiclinks.FirebaseDynamicLinks;
import com.google.firebase.dynamiclinks.ShortDynamicLink;
import com.google.firebase.dynamiclinks.PendingDynamicLinkData;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.firebase.dynamiclinks.ShortDynamicLink;
import io.invertase.firebase.Utils;
@ -47,7 +45,10 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
public void createDynamicLink(final ReadableMap linkData, final Promise promise) {
try {
DynamicLink.Builder builder = getDynamicLinkBuilder(linkData);
String link = builder.buildDynamicLink().getUri().toString();
String link = builder
.buildDynamicLink()
.getUri()
.toString();
Log.d(TAG, "created dynamic link: " + link);
promise.resolve(link);
} catch (Exception ex) {
@ -57,7 +58,11 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
}
@ReactMethod
public void createShortDynamicLink(final ReadableMap linkData, final String type, final Promise promise) {
public void createShortDynamicLink(
final ReadableMap linkData,
final String type,
final Promise promise
) {
try {
DynamicLink.Builder builder = getDynamicLinkBuilder(linkData);
Task<ShortDynamicLink> shortLinkTask;
@ -70,16 +75,30 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
}
shortLinkTask.addOnCompleteListener(new OnCompleteListener<ShortDynamicLink>() {
@Override
public void onComplete(@NonNull Task<ShortDynamicLink> task) {
if (task.isSuccessful()) {
String shortLink = task.getResult().getShortLink().toString();
Log.d(TAG, "created short dynamic link: " + shortLink);
promise.resolve(shortLink);
} else {
Log.e(TAG, "create short dynamic link failure " + task.getException().getMessage());
promise.reject("links/failure", task.getException().getMessage(), task.getException());
}
@Override
public void onComplete(@NonNull Task<ShortDynamicLink> task) {
if (task.isSuccessful()) {
String shortLink = task
.getResult()
.getShortLink()
.toString();
Log.d(TAG, "created short dynamic link: " + shortLink);
promise.resolve(shortLink);
} else {
Log.e(
TAG,
"create short dynamic link failure " + task
.getException()
.getMessage()
);
promise.reject(
"links/failure",
task
.getException()
.getMessage(),
task.getException()
);
}
}
});
} catch (Exception ex) {
@ -94,7 +113,8 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
promise.resolve(mInitialLink);
} else {
if (getCurrentActivity() != null) {
FirebaseDynamicLinks.getInstance()
FirebaseDynamicLinks
.getInstance()
.getDynamicLink(getCurrentActivity().getIntent())
.addOnSuccessListener(new OnSuccessListener<PendingDynamicLinkData>() {
@Override
@ -102,7 +122,9 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
if (pendingDynamicLinkData != null
&& !isInvitation(pendingDynamicLinkData)) {
mInitialLink = pendingDynamicLinkData.getLink().toString();
mInitialLink = pendingDynamicLinkData
.getLink()
.toString();
}
Log.d(TAG, "getInitialLink: link is: " + mInitialLink);
mInitialLinkInitialized = true;
@ -133,15 +155,22 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
@Override
public void onNewIntent(Intent intent) {
FirebaseDynamicLinks.getInstance()
FirebaseDynamicLinks
.getInstance()
.getDynamicLink(intent)
.addOnSuccessListener(new OnSuccessListener<PendingDynamicLinkData>() {
@Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
if (pendingDynamicLinkData != null
&& !isInvitation(pendingDynamicLinkData)) {
String link = pendingDynamicLinkData.getLink().toString();
Utils.sendEvent(getReactApplicationContext(), "links_link_received", link);
String link = pendingDynamicLinkData
.getLink()
.toString();
Utils.sendEvent(
getReactApplicationContext(),
"links_link_received",
link
);
}
}
});
@ -175,14 +204,18 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
// Looks at the internals of the link data to detect whether it's an invitation or not
private boolean isInvitation(PendingDynamicLinkData pendingDynamicLinkData) {
FirebaseAppInvite invite = FirebaseAppInvite.getInvitation(pendingDynamicLinkData);
if (invite != null && invite.getInvitationId() != null && !invite.getInvitationId().isEmpty()) {
if (invite != null && invite.getInvitationId() != null && !invite
.getInvitationId()
.isEmpty()) {
return true;
}
return false;
}
private DynamicLink.Builder getDynamicLinkBuilder(final ReadableMap linkData) {
DynamicLink.Builder builder = FirebaseDynamicLinks.getInstance().createDynamicLink();
DynamicLink.Builder builder = FirebaseDynamicLinks
.getInstance()
.createDynamicLink();
try {
builder.setLink(Uri.parse(linkData.getString("link")));
builder.setDynamicLinkDomain(linkData.getString("dynamicLinkDomain"));
@ -199,7 +232,10 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
return builder;
}
private void setAnalyticsParameters(final ReadableMap analyticsData, final DynamicLink.Builder builder) {
private void setAnalyticsParameters(
final ReadableMap analyticsData,
final DynamicLink.Builder builder
) {
DynamicLink.GoogleAnalyticsParameters.Builder analyticsParameters = new DynamicLink.GoogleAnalyticsParameters.Builder();
if (analyticsData.hasKey("campaign")) {
@ -220,9 +256,13 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
builder.setGoogleAnalyticsParameters(analyticsParameters.build());
}
private void setAndroidParameters(final ReadableMap androidData, final DynamicLink.Builder builder) {
private void setAndroidParameters(
final ReadableMap androidData,
final DynamicLink.Builder builder
) {
if (androidData.hasKey("packageName")) {
DynamicLink.AndroidParameters.Builder androidParameters = new DynamicLink.AndroidParameters.Builder(androidData.getString("packageName"));
DynamicLink.AndroidParameters.Builder androidParameters = new DynamicLink.AndroidParameters.Builder(
androidData.getString("packageName"));
if (androidData.hasKey("fallbackUrl")) {
androidParameters.setFallbackUrl(Uri.parse(androidData.getString("fallbackUrl")));
@ -261,7 +301,10 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
}
}
private void setITunesParameters(final ReadableMap itunesData, final DynamicLink.Builder builder) {
private void setITunesParameters(
final ReadableMap itunesData,
final DynamicLink.Builder builder
) {
DynamicLink.ItunesConnectAnalyticsParameters.Builder itunesParameters = new DynamicLink.ItunesConnectAnalyticsParameters.Builder();
if (itunesData.hasKey("affiliateToken")) {
@ -276,16 +319,23 @@ public class RNFirebaseLinks extends ReactContextBaseJavaModule implements Activ
builder.setItunesConnectAnalyticsParameters(itunesParameters.build());
}
private void setNavigationParameters(final ReadableMap navigationData, final DynamicLink.Builder builder) {
private void setNavigationParameters(
final ReadableMap navigationData,
final DynamicLink.Builder builder
) {
DynamicLink.NavigationInfoParameters.Builder navigationParameters = new DynamicLink.NavigationInfoParameters.Builder();
if (navigationData.hasKey("forcedRedirectEnabled")) {
navigationParameters.setForcedRedirectEnabled(navigationData.getBoolean("forcedRedirectEnabled"));
navigationParameters.setForcedRedirectEnabled(navigationData.getBoolean(
"forcedRedirectEnabled"));
}
builder.setNavigationInfoParameters(navigationParameters.build());
}
private void setSocialParameters(final ReadableMap socialData, final DynamicLink.Builder builder) {
private void setSocialParameters(
final ReadableMap socialData,
final DynamicLink.Builder builder
) {
DynamicLink.SocialMetaTagParameters.Builder socialParameters = new DynamicLink.SocialMetaTagParameters.Builder();
if (socialData.hasKey("descriptionText")) {

View File

@ -1,7 +1,6 @@
package io.invertase.firebase.links;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.UIManagerModule;

View File

@ -39,9 +39,9 @@ import java.util.Map;
* com.facebook.internal is solely for the use of other packages within the Facebook SDK for
* Android. Use of any of the classes in this package is unsupported, and they may be modified or
* removed without warning at any time.
*
* <p>
* A helper class that can round trip between JSON and Bundle objects that contains the types:
* Boolean, Integer, Long, Double, String
* Boolean, Integer, Long, Double, String
* If other types are found, an IllegalArgumentException is thrown.
*/
public class BundleJSONConverter {
@ -126,13 +126,13 @@ public class BundleJSONConverter {
} else if (jsonArray.get(0) instanceof Boolean) {
boolean[] booleanArray = new boolean[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
booleanArray[i] = (Boolean)jsonArray.get(i);
booleanArray[i] = (Boolean) jsonArray.get(i);
}
bundle.putBooleanArray(key, booleanArray);
} else if (jsonArray.get(0) instanceof Double) {
double[] doubleArray = new double[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
doubleArray[i] = (Double)jsonArray.get(i);
doubleArray[i] = (Double) jsonArray.get(i);
}
bundle.putDoubleArray(key, doubleArray);
} else if (jsonArray.get(0) instanceof Long) {
@ -143,12 +143,14 @@ public class BundleJSONConverter {
bundle.putLongArray(key, longArray);
} else if (jsonArray.get(0) instanceof JSONObject) {
ArrayList<Bundle> bundleArrayList = new ArrayList<>();
for (int i =0; i < jsonArray.length(); i++) {
for (int i = 0; i < jsonArray.length(); i++) {
bundleArrayList.add(convertToBundle((JSONObject) jsonArray.get(i)));
}
bundle.putSerializable(key, bundleArrayList);
} else {
throw new IllegalArgumentException("Unexpected type in an array: " + jsonArray.get(0).getClass());
throw new IllegalArgumentException("Unexpected type in an array: " + jsonArray
.get(0)
.getClass());
}
}
@ -159,12 +161,6 @@ public class BundleJSONConverter {
});
}
public interface Setter {
public void setOnBundle(Bundle bundle, String key, Object value) throws JSONException;
public void setOnJSON(JSONObject json, String key, Object value) throws JSONException;
}
public static JSONObject convertToJSON(Bundle bundle) throws JSONException {
JSONObject json = new JSONObject();
@ -239,4 +235,10 @@ public class BundleJSONConverter {
return bundle;
}
public interface Setter {
public void setOnBundle(Bundle bundle, String key, Object value) throws JSONException;
public void setOnJSON(JSONObject json, String key, Object value) throws JSONException;
}
}

View File

@ -6,7 +6,6 @@ import com.google.firebase.messaging.RemoteMessage;
import java.util.Map;
public class MessagingSerializer {
public static WritableMap parseRemoteMessage(RemoteMessage message) {
WritableMap messageMap = Arguments.createMap();
@ -17,7 +16,9 @@ public class MessagingSerializer {
}
if (message.getData() != null) {
for (Map.Entry<String, String> e : message.getData().entrySet()) {
for (Map.Entry<String, String> e : message
.getData()
.entrySet()) {
dataMap.putString(e.getKey(), e.getValue());
}
}

View File

@ -4,7 +4,6 @@ import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.HeadlessJsTaskService;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
import com.google.firebase.messaging.RemoteMessage;
@ -13,7 +12,8 @@ import javax.annotation.Nullable;
public class RNFirebaseBackgroundMessagingService extends HeadlessJsTaskService {
@Override
protected @Nullable HeadlessJsTaskConfig getTaskConfig(Intent intent) {
protected @Nullable
HeadlessJsTaskConfig getTaskConfig(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
RemoteMessage message = intent.getParcelableExtra("message");

View File

@ -1,6 +1,5 @@
package io.invertase.firebase.messaging;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
@ -8,8 +7,8 @@ import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceIdService;
public class RNFirebaseInstanceIdService extends FirebaseInstanceIdService {
private static final String TAG = "RNFInstanceIdService";
public static final String TOKEN_REFRESH_EVENT = "messaging-token-refresh";
private static final String TAG = "RNFInstanceIdService";
@Override
public void onTokenRefresh() {
@ -19,6 +18,8 @@ public class RNFirebaseInstanceIdService extends FirebaseInstanceIdService {
Intent tokenRefreshEvent = new Intent(TOKEN_REFRESH_EVENT);
// Broadcast it so it is only available to the RN Application
LocalBroadcastManager.getInstance(this).sendBroadcast(tokenRefreshEvent);
LocalBroadcastManager
.getInstance(this)
.sendBroadcast(tokenRefreshEvent);
}
}

View File

@ -5,8 +5,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.facebook.react.bridge.Promise;
@ -32,12 +32,16 @@ public class RNFirebaseMessaging extends ReactContextBaseJavaModule {
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
// Subscribe to message events
localBroadcastManager.registerReceiver(new MessageReceiver(),
new IntentFilter(RNFirebaseMessagingService.MESSAGE_EVENT));
localBroadcastManager.registerReceiver(
new MessageReceiver(),
new IntentFilter(RNFirebaseMessagingService.MESSAGE_EVENT)
);
// Subscribe to token refresh events
localBroadcastManager.registerReceiver(new RefreshTokenReceiver(),
new IntentFilter(RNFirebaseInstanceIdService.TOKEN_REFRESH_EVENT));
localBroadcastManager.registerReceiver(
new RefreshTokenReceiver(),
new IntentFilter(RNFirebaseInstanceIdService.TOKEN_REFRESH_EVENT)
);
}
@Override
@ -47,7 +51,9 @@ public class RNFirebaseMessaging extends ReactContextBaseJavaModule {
@ReactMethod
public void getToken(Promise promise) {
String token = FirebaseInstanceId.getInstance().getToken();
String token = FirebaseInstanceId
.getInstance()
.getToken();
Log.d(TAG, "Firebase token: " + token);
promise.resolve(token);
}
@ -60,7 +66,9 @@ public class RNFirebaseMessaging extends ReactContextBaseJavaModule {
// Non Web SDK methods
@ReactMethod
public void hasPermission(Promise promise) {
Boolean enabled = NotificationManagerCompat.from(getReactApplicationContext()).areNotificationsEnabled();
Boolean enabled = NotificationManagerCompat
.from(getReactApplicationContext())
.areNotificationsEnabled();
promise.resolve(enabled);
}
@ -94,7 +102,9 @@ public class RNFirebaseMessaging extends ReactContextBaseJavaModule {
}
}
FirebaseMessaging.getInstance().send(mb.build());
FirebaseMessaging
.getInstance()
.send(mb.build());
// TODO: Listen to onMessageSent and onSendError for better feedback?
promise.resolve(null);
@ -102,36 +112,42 @@ public class RNFirebaseMessaging extends ReactContextBaseJavaModule {
@ReactMethod
public void subscribeToTopic(String topic, final Promise promise) {
FirebaseMessaging.getInstance().subscribeToTopic(topic).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "subscribeToTopic:onComplete:success");
promise.resolve(null);
} else {
Exception exception = task.getException();
Log.e(TAG, "subscribeToTopic:onComplete:failure", exception);
promise.reject(exception);
FirebaseMessaging
.getInstance()
.subscribeToTopic(topic)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "subscribeToTopic:onComplete:success");
promise.resolve(null);
} else {
Exception exception = task.getException();
Log.e(TAG, "subscribeToTopic:onComplete:failure", exception);
promise.reject(exception);
}
}
}
});
});
}
@ReactMethod
public void unsubscribeFromTopic(String topic, final Promise promise) {
FirebaseMessaging.getInstance().unsubscribeFromTopic(topic).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "unsubscribeFromTopic:onComplete:success");
promise.resolve(null);
} else {
Exception exception = task.getException();
Log.e(TAG, "unsubscribeFromTopic:onComplete:failure", exception);
promise.reject(exception);
FirebaseMessaging
.getInstance()
.unsubscribeFromTopic(topic)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "unsubscribeFromTopic:onComplete:success");
promise.resolve(null);
} else {
Exception exception = task.getException();
Log.e(TAG, "unsubscribeFromTopic:onComplete:failure", exception);
promise.reject(exception);
}
}
}
});
});
}
private class MessageReceiver extends BroadcastReceiver {
@ -152,7 +168,9 @@ public class RNFirebaseMessaging extends ReactContextBaseJavaModule {
@Override
public void onReceive(Context context, Intent intent) {
if (getReactApplicationContext().hasActiveCatalystInstance()) {
String token = FirebaseInstanceId.getInstance().getToken();
String token = FirebaseInstanceId
.getInstance()
.getToken();
Log.d(TAG, "Received new FCM token: " + token);
Utils.sendEvent(getReactApplicationContext(), "messaging_token_refreshed", token);

View File

@ -11,9 +11,9 @@ import com.google.firebase.messaging.RemoteMessage;
import io.invertase.firebase.Utils;
public class RNFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "RNFMessagingService";
public static final String MESSAGE_EVENT = "messaging-message";
public static final String REMOTE_NOTIFICATION_EVENT = "notifications-remote-notification";
private static final String TAG = "RNFMessagingService";
@Override
public void onMessageReceived(RemoteMessage message) {
@ -25,7 +25,9 @@ public class RNFirebaseMessagingService extends FirebaseMessagingService {
notificationEvent.putExtra("notification", message);
// Broadcast it to the (foreground) RN Application
LocalBroadcastManager.getInstance(this).sendBroadcast(notificationEvent);
LocalBroadcastManager
.getInstance(this)
.sendBroadcast(notificationEvent);
} else {
// It's a data message
// If the app is in the foreground we send it to the Messaging module
@ -33,16 +35,27 @@ public class RNFirebaseMessagingService extends FirebaseMessagingService {
Intent messagingEvent = new Intent(MESSAGE_EVENT);
messagingEvent.putExtra("message", message);
// Broadcast it so it is only available to the RN Application
LocalBroadcastManager.getInstance(this).sendBroadcast(messagingEvent);
LocalBroadcastManager
.getInstance(this)
.sendBroadcast(messagingEvent);
} else {
try {
// If the app is in the background we send it to the Headless JS Service
Intent headlessIntent = new Intent(this.getApplicationContext(), RNFirebaseBackgroundMessagingService.class);
Intent headlessIntent = new Intent(
this.getApplicationContext(),
RNFirebaseBackgroundMessagingService.class
);
headlessIntent.putExtra("message", message);
this.getApplicationContext().startService(headlessIntent);
this
.getApplicationContext()
.startService(headlessIntent);
HeadlessJsTaskService.acquireWakeLockNow(this.getApplicationContext());
} catch (IllegalStateException ex) {
Log.e(TAG, "Background messages will only work if the message priority is set to 'high'", ex);
Log.e(
TAG,
"Background messages will only work if the message priority is set to 'high'",
ex
);
}
}
}

View File

@ -37,9 +37,11 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
private final Promise promise;
private ReactApplicationContext reactContext;
public DisplayNotificationTask(Context context, ReactApplicationContext reactContext,
NotificationManager notificationManager,
Bundle notification, Promise promise) {
public DisplayNotificationTask(
Context context, ReactApplicationContext reactContext,
NotificationManager notificationManager,
Bundle notification, Promise promise
) {
this.context = context;
this.notification = notification;
this.notificationManager = notificationManager;
@ -53,7 +55,10 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
Class intentClass = getMainActivityClass();
if (intentClass == null) {
if (promise != null) {
promise.reject("notification/display_notification_error", "Could not find main activity class");
promise.reject(
"notification/display_notification_error",
"Could not find main activity class"
);
}
return null;
}
@ -77,7 +82,10 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
nb = nb.setExtras(notification.getBundle("data"));
}
if (notification.containsKey("sound")) {
Uri sound = RNFirebaseNotificationManager.getSound(context, notification.getString("sound"));
Uri sound = RNFirebaseNotificationManager.getSound(
context,
notification.getString("sound")
);
nb = nb.setSound(sound);
}
if (notification.containsKey("subtitle")) {
@ -148,7 +156,7 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
if (defaults == 0) {
ArrayList<Integer> defaultsArray = android.getIntegerArrayList("defaults");
if(defaultsArray != null) {
if (defaultsArray != null) {
for (Integer defaultValue : defaultsArray) {
defaults |= defaultValue;
}
@ -210,7 +218,11 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
Bundle progress = android.getBundle("progress");
Double max = progress.getDouble("max");
Double progressI = progress.getDouble("progress");
nb = nb.setProgress(max.intValue(), progressI.intValue(), progress.getBoolean("indeterminate"));
nb = nb.setProgress(
max.intValue(),
progressI.intValue(),
progress.getBoolean("indeterminate")
);
}
// TODO: Public version of notification
/* if (android.containsKey("publicVersion")) {
@ -253,10 +265,12 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
}
if (android.containsKey("vibrate")) {
ArrayList<Integer> vibrate = android.getIntegerArrayList("vibrate");
if(vibrate != null) {
if (vibrate != null) {
long[] vibrateArray = new long[vibrate.size()];
for (int i = 0; i < vibrate.size(); i++) {
vibrateArray[i] = vibrate.get(i).longValue();
vibrateArray[i] = vibrate
.get(i)
.longValue();
}
nb = nb.setVibrate(vibrateArray);
}
@ -281,11 +295,15 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
String tag = null;
if (android.containsKey("tag")) {
tag = android.getString("tag");
tag = android.getString("tag");
}
// Create the notification intent
PendingIntent contentIntent = createIntent(intentClass, notification, android.getString("clickAction"));
PendingIntent contentIntent = createIntent(
intentClass,
notification,
android.getString("clickAction")
);
nb = nb.setContentIntent(contentIntent);
// Build the notification and send it
@ -293,7 +311,11 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
notificationManager.notify(tag, notificationId.hashCode(), builtNotification);
if (reactContext != null) {
Utils.sendEvent(reactContext, "notifications_notification_displayed", Arguments.fromBundle(notification));
Utils.sendEvent(
reactContext,
"notifications_notification_displayed",
Arguments.fromBundle(notification)
);
}
if (promise != null) {
@ -310,8 +332,13 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
return null;
}
private NotificationCompat.Action createAction(Bundle action, Class intentClass, Bundle notification) {
boolean showUserInterface = action.containsKey("showUserInterface") && action.getBoolean("showUserInterface");
private NotificationCompat.Action createAction(
Bundle action,
Class intentClass,
Bundle notification
) {
boolean showUserInterface = action.containsKey("showUserInterface") && action.getBoolean(
"showUserInterface");
String actionKey = action.getString("action");
PendingIntent actionIntent = showUserInterface ?
createIntent(intentClass, notification, actionKey) :
@ -319,7 +346,11 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
int icon = getIcon(action.getString("icon"));
String title = action.getString("title");
NotificationCompat.Action.Builder ab = new NotificationCompat.Action.Builder(icon, title, actionIntent);
NotificationCompat.Action.Builder ab = new NotificationCompat.Action.Builder(
icon,
title,
actionIntent
);
if (action.containsKey("allowGeneratedReplies")) {
ab = ab.setAllowGeneratedReplies(action.getBoolean("allowGeneratedReplies"));
@ -353,7 +384,12 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
}
String notificationId = notification.getString("notificationId");
return PendingIntent.getActivity(context, notificationId.hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
return PendingIntent.getActivity(
context,
notificationId.hashCode(),
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
}
private PendingIntent createBroadcastIntent(Bundle notification, String action) {
@ -365,7 +401,12 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
intent.setAction("io.invertase.firebase.notifications.BackgroundAction");
intent.putExtra("action", action);
intent.putExtra("notification", notification);
return PendingIntent.getBroadcast(context, notificationId.hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
return PendingIntent.getBroadcast(
context,
notificationId.hashCode(),
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);
}
private RemoteInput createRemoteInput(Bundle remoteInput) {
@ -417,18 +458,22 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
}
private int getIcon(String icon) {
int resourceId = RNFirebaseNotificationManager.getResourceId(context,"mipmap", icon);
int resourceId = RNFirebaseNotificationManager.getResourceId(context, "mipmap", icon);
if (resourceId == 0) {
resourceId = RNFirebaseNotificationManager.getResourceId(context,"drawable", icon);
resourceId = RNFirebaseNotificationManager.getResourceId(context, "drawable", icon);
}
return resourceId;
}
private Class getMainActivityClass() {
String packageName = context.getPackageName();
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
Intent launchIntent = context
.getPackageManager()
.getLaunchIntentForPackage(packageName);
try {
return Class.forName(launchIntent.getComponent().getClassName());
return Class.forName(launchIntent
.getComponent()
.getClassName());
} catch (ClassNotFoundException e) {
Log.e(TAG, "Failed to get main activity class", e);
return null;

View File

@ -36,12 +36,18 @@ public class RNFirebaseBackgroundNotificationActionReceiver extends BroadcastRec
if (Utils.isAppInForeground(context)) {
WritableMap notificationOpenMap = toNotificationOpenMap(intent);
ReactApplication reactApplication = (ReactApplication)context.getApplicationContext();
ReactContext reactContext = reactApplication.getReactNativeHost().getReactInstanceManager().getCurrentReactContext();
ReactApplication reactApplication = (ReactApplication) context.getApplicationContext();
ReactContext reactContext = reactApplication
.getReactNativeHost()
.getReactInstanceManager()
.getCurrentReactContext();
Utils.sendEvent(reactContext, "notifications_notification_opened", notificationOpenMap);
} else {
Intent serviceIntent = new Intent(context, RNFirebaseBackgroundNotificationActionsService.class);
Intent serviceIntent = new Intent(
context,
RNFirebaseBackgroundNotificationActionsService.class
);
serviceIntent.putExtras(intent.getExtras());
context.startService(serviceIntent);
HeadlessJsTaskService.acquireWakeLockNow(context);

View File

@ -13,7 +13,8 @@ import static io.invertase.firebase.notifications.RNFirebaseBackgroundNotificati
public class RNFirebaseBackgroundNotificationActionsService extends HeadlessJsTaskService {
@Override
protected @Nullable HeadlessJsTaskConfig getTaskConfig(Intent intent) {
protected @Nullable
HeadlessJsTaskConfig getTaskConfig(Intent intent) {
if (isBackgroundNotficationIntent(intent)) {
WritableMap notificationOpenMap = toNotificationOpenMap(intent);

View File

@ -2,7 +2,6 @@ package io.invertase.firebase.notifications;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
@ -10,8 +9,6 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.media.RingtoneManager;
import android.net.Uri;
@ -19,8 +16,6 @@ import android.os.Build;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.RemoteInput;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
@ -33,9 +28,6 @@ import com.facebook.react.bridge.ReadableMap;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
@ -45,8 +37,8 @@ import io.invertase.firebase.Utils;
import io.invertase.firebase.messaging.BundleJSONConverter;
public class RNFirebaseNotificationManager {
private static final String PREFERENCES_KEY = "RNFNotifications";
public static final String SCHEDULED_NOTIFICATION_EVENT = "notifications-scheduled-notification";
private static final String PREFERENCES_KEY = "RNFNotifications";
private static final String TAG = "RNFNotificationManager";
private AlarmManager alarmManager;
private Context context;
@ -62,31 +54,63 @@ public class RNFirebaseNotificationManager {
public RNFirebaseNotificationManager(Context context) {
this.alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
this.context = context;
this.notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
this.notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
this.preferences = context.getSharedPreferences(PREFERENCES_KEY, Context.MODE_PRIVATE);
}
public static int getResourceId(Context context, String type, String image) {
return context
.getResources()
.getIdentifier(image, type, context.getPackageName());
}
public static Uri getSound(Context context, String sound) {
if (sound == null) {
return null;
} else if (sound.contains("://")) {
return Uri.parse(sound);
} else if (sound.equalsIgnoreCase("default")) {
return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
} else {
int soundResourceId = getResourceId(context, "raw", sound);
if (soundResourceId == 0) {
soundResourceId = getResourceId(context, "raw", sound.substring(0, sound.lastIndexOf('.')));
}
return Uri.parse("android.resource://" + context.getPackageName() + "/" + soundResourceId);
}
}
public void cancelAllNotifications(Promise promise) {
try {
Map<String, ?> notifications = preferences.getAll();
for(String notificationId : notifications.keySet()){
for (String notificationId : notifications.keySet()) {
cancelAlarm(notificationId);
}
preferences.edit().clear().apply();
preferences
.edit()
.clear()
.apply();
promise.resolve(null);
} catch (SecurityException e) {
// TODO: Identify what these situations are
// In some devices/situations cancelAllLocalNotifications can throw a SecurityException.
Log.e(TAG, e.getMessage());
promise.reject("notification/cancel_notifications_error", "Could not cancel notifications", e);
promise.reject(
"notification/cancel_notifications_error",
"Could not cancel notifications",
e
);
}
}
public void cancelNotification(String notificationId, Promise promise) {
try {
cancelAlarm(notificationId);
preferences.edit().remove(notificationId).apply();
preferences
.edit()
.remove(notificationId)
.apply();
promise.resolve(null);
} catch (SecurityException e) {
// TODO: Identify what these situations are
@ -151,10 +175,17 @@ public class RNFirebaseNotificationManager {
public void displayScheduledNotification(Bundle notification) {
// If this isn't a repeated notification, clear it from the scheduled notifications list
if (!notification.getBundle("schedule").containsKey("repeated")
|| !notification.getBundle("schedule").getBoolean("repeated")) {
if (!notification
.getBundle("schedule")
.containsKey("repeated")
|| !notification
.getBundle("schedule")
.getBoolean("repeated")) {
String notificationId = notification.getString("notificationId");
preferences.edit().remove(notificationId).apply();
preferences
.edit()
.remove(notificationId)
.apply();
}
if (Utils.isAppInForeground(context)) {
@ -162,21 +193,23 @@ public class RNFirebaseNotificationManager {
// It is up to the JS to decide whether to display the notification
Intent scheduledNotificationEvent = new Intent(SCHEDULED_NOTIFICATION_EVENT);
scheduledNotificationEvent.putExtra("notification", notification);
LocalBroadcastManager.getInstance(context).sendBroadcast(scheduledNotificationEvent);
LocalBroadcastManager
.getInstance(context)
.sendBroadcast(scheduledNotificationEvent);
} else {
// If the app is in the background, then we display it automatically
displayNotification(notification, null);
}
}
public ArrayList<Bundle> getScheduledNotifications(){
public ArrayList<Bundle> getScheduledNotifications() {
ArrayList<Bundle> array = new ArrayList<>();
Map<String, ?> notifications = preferences.getAll();
for(String notificationId : notifications.keySet()){
for (String notificationId : notifications.keySet()) {
try {
JSONObject json = new JSONObject((String)notifications.get(notificationId));
JSONObject json = new JSONObject((String) notifications.get(notificationId));
Bundle bundle = BundleJSONConverter.convertToBundle(json);
array.add(bundle);
} catch (JSONException e) {
@ -199,16 +232,16 @@ public class RNFirebaseNotificationManager {
public void removeDeliveredNotificationsByTag(String tag, Promise promise) {
StatusBarNotification[] statusBarNotifications = notificationManager.getActiveNotifications();
for (StatusBarNotification statusBarNotification : statusBarNotifications) {
if (statusBarNotification.getTag() == tag) {
notificationManager.cancel(statusBarNotification.getTag(), statusBarNotification.getId());
}
if (statusBarNotification.getTag() == tag) {
notificationManager.cancel(statusBarNotification.getTag(), statusBarNotification.getId());
}
}
promise.resolve(null);
}
public void rescheduleNotifications() {
ArrayList<Bundle> bundles = getScheduledNotifications();
for(Bundle bundle: bundles){
for (Bundle bundle : bundles) {
scheduleNotification(bundle, null);
}
}
@ -221,32 +254,23 @@ public class RNFirebaseNotificationManager {
private void cancelAlarm(String notificationId) {
Intent notificationIntent = new Intent(context, RNFirebaseNotificationReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notificationId.hashCode(), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
notificationId.hashCode(),
notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
alarmManager.cancel(pendingIntent);
}
private void displayNotification(Bundle notification, Promise promise) {
new DisplayNotificationTask(context, reactContext, notificationManager, notification, promise).execute();
}
public static int getResourceId(Context context, String type, String image) {
return context.getResources().getIdentifier(image, type, context.getPackageName());
}
public static Uri getSound(Context context, String sound) {
if (sound == null) {
return null;
} else if (sound.contains("://")) {
return Uri.parse(sound);
} else if (sound.equalsIgnoreCase("default")) {
return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
} else {
int soundResourceId = getResourceId(context,"raw", sound);
if (soundResourceId == 0) {
soundResourceId = getResourceId(context,"raw", sound.substring(0, sound.lastIndexOf('.')));
}
return Uri.parse("android.resource://" + context.getPackageName() + "/" + soundResourceId);
}
new DisplayNotificationTask(
context,
reactContext,
notificationManager,
notification,
promise
).execute();
}
private NotificationChannelGroup parseChannelGroupMap(ReadableMap channelGroupMap) {
@ -356,20 +380,31 @@ public class RNFirebaseNotificationManager {
// We store them so that they can be re-scheduled when the phone restarts in RNFirebaseNotificationsRebootReceiver
try {
JSONObject json = BundleJSONConverter.convertToJSON(notification);
preferences.edit().putString(notificationId, json.toString()).apply();
preferences
.edit()
.putString(notificationId, json.toString())
.apply();
} catch (JSONException e) {
if (promise == null) {
Log.e(TAG, "Failed to store notification");
} else {
promise.reject("notification/schedule_notification_error", "Failed to store notification", e);
promise.reject(
"notification/schedule_notification_error",
"Failed to store notification",
e
);
}
return;
}
Intent notificationIntent = new Intent(context, RNFirebaseNotificationReceiver.class);
notificationIntent.putExtras(notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notificationId.hashCode(),
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
notificationId.hashCode(),
notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
if (schedule.containsKey("repeatInterval")) {
// If fireDate you specify is in the past, the alarm triggers immediately.

View File

@ -41,6 +41,7 @@ public class RNFirebaseNotifications extends ReactContextBaseJavaModule implemen
private SharedPreferences sharedPreferences = null;
private RNFirebaseNotificationManager notificationManager;
public RNFirebaseNotifications(ReactApplicationContext context) {
super(context);
context.addActivityEventListener(this);
@ -51,12 +52,16 @@ public class RNFirebaseNotifications extends ReactContextBaseJavaModule implemen
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
// Subscribe to remote notification events
localBroadcastManager.registerReceiver(new RemoteNotificationReceiver(),
new IntentFilter(RNFirebaseMessagingService.REMOTE_NOTIFICATION_EVENT));
localBroadcastManager.registerReceiver(
new RemoteNotificationReceiver(),
new IntentFilter(RNFirebaseMessagingService.REMOTE_NOTIFICATION_EVENT)
);
// Subscribe to scheduled notification events
localBroadcastManager.registerReceiver(new ScheduledNotificationReceiver(),
new IntentFilter(RNFirebaseNotificationManager.SCHEDULED_NOTIFICATION_EVENT));
localBroadcastManager.registerReceiver(
new ScheduledNotificationReceiver(),
new IntentFilter(RNFirebaseNotificationManager.SCHEDULED_NOTIFICATION_EVENT)
);
}
@Override
@ -123,7 +128,10 @@ public class RNFirebaseNotifications extends ReactContextBaseJavaModule implemen
@ReactMethod
public void setBadge(int badge, Promise promise) {
// Store the badge count for later retrieval
sharedPreferences.edit().putInt(BADGE_KEY, badge).apply();
sharedPreferences
.edit()
.putInt(BADGE_KEY, badge)
.apply();
if (badge == 0) {
Log.d(TAG, "Remove badge count");
ShortcutBadger.removeCount(this.getReactApplicationContext());
@ -193,7 +201,11 @@ public class RNFirebaseNotifications extends ReactContextBaseJavaModule implemen
public void onNewIntent(Intent intent) {
WritableMap notificationOpenMap = parseIntentForNotification(intent);
if (notificationOpenMap != null) {
Utils.sendEvent(getReactApplicationContext(), "notifications_notification_opened", notificationOpenMap);
Utils.sendEvent(
getReactApplicationContext(),
"notifications_notification_opened",
notificationOpenMap
);
}
}
@ -277,7 +289,9 @@ public class RNFirebaseNotifications extends ReactContextBaseJavaModule implemen
notificationMap.putString("body", body);
}
if (message.getData() != null) {
for (Map.Entry<String, String> e : message.getData().entrySet()) {
for (Map.Entry<String, String> e : message
.getData()
.entrySet()) {
dataMap.putString(e.getKey(), e.getValue());
}
}
@ -315,27 +329,33 @@ public class RNFirebaseNotifications extends ReactContextBaseJavaModule implemen
return notificationMap;
}
private @Nullable String getNotificationBody(RemoteMessage.Notification notification) {
private @Nullable
String getNotificationBody(RemoteMessage.Notification notification) {
String body = notification.getBody();
String bodyLocKey = notification.getBodyLocalizationKey();
if (bodyLocKey != null) {
String[] bodyLocArgs = notification.getBodyLocalizationArgs();
Context ctx = getReactApplicationContext();
int resId = getResId(ctx, bodyLocKey);
return ctx.getResources().getString(resId, (Object[]) bodyLocArgs);
return ctx
.getResources()
.getString(resId, (Object[]) bodyLocArgs);
} else {
return body;
}
}
private @Nullable String getNotificationTitle(RemoteMessage.Notification notification) {
private @Nullable
String getNotificationTitle(RemoteMessage.Notification notification) {
String title = notification.getTitle();
String titleLocKey = notification.getTitleLocalizationKey();
if (titleLocKey != null) {
String[] titleLocArgs = notification.getTitleLocalizationArgs();
Context ctx = getReactApplicationContext();
int resId = getResId(ctx, titleLocKey);
return ctx.getResources().getString(resId, (Object[]) titleLocArgs);
return ctx
.getResources()
.getString(resId, (Object[]) titleLocArgs);
} else {
return title;
}
@ -350,7 +370,11 @@ public class RNFirebaseNotifications extends ReactContextBaseJavaModule implemen
RemoteMessage message = intent.getParcelableExtra("notification");
WritableMap messageMap = parseRemoteMessage(message);
Utils.sendEvent(getReactApplicationContext(), "notifications_notification_received", messageMap);
Utils.sendEvent(
getReactApplicationContext(),
"notifications_notification_received",
messageMap
);
}
}
}
@ -364,7 +388,11 @@ public class RNFirebaseNotifications extends ReactContextBaseJavaModule implemen
Bundle notification = intent.getBundleExtra("notification");
WritableMap messageMap = parseNotificationBundle(notification);
Utils.sendEvent(getReactApplicationContext(), "notifications_notification_received", messageMap);
Utils.sendEvent(
getReactApplicationContext(),
"notifications_notification_received",
messageMap
);
}
}
}

View File

@ -41,7 +41,6 @@ import com.google.firebase.storage.OnProgressListener;
import io.invertase.firebase.Utils;
@SuppressWarnings("WeakerAccess")
public class RNFirebaseStorage extends ReactContextBaseJavaModule {
@ -111,17 +110,20 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
@ReactMethod
public void delete(String appName, final String path, final Promise promise) {
StorageReference reference = this.getReference(path, appName);
reference.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
promise.resolve(null);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
promiseRejectStorageException(promise, exception);
}
});
reference
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
promise.resolve(null);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
promiseRejectStorageException(promise, exception);
}
});
}
/**
@ -162,17 +164,20 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
@ReactMethod
public void getMetadata(String appName, final String path, final Promise promise) {
StorageReference reference = this.getReference(path, appName);
reference.getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
@Override
public void onSuccess(StorageMetadata storageMetadata) {
promise.resolve(getMetadataAsMap(storageMetadata));
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
promiseRejectStorageException(promise, exception);
}
});
reference
.getMetadata()
.addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
@Override
public void onSuccess(StorageMetadata storageMetadata) {
promise.resolve(getMetadataAsMap(storageMetadata));
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
promiseRejectStorageException(promise, exception);
}
});
}
/**
@ -184,22 +189,30 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#updateMetadata
*/
@ReactMethod
public void updateMetadata(String appName, final String path, final ReadableMap metadata, final Promise promise) {
public void updateMetadata(
String appName,
final String path,
final ReadableMap metadata,
final Promise promise
) {
StorageReference reference = this.getReference(path, appName);
StorageMetadata md = buildMetadataFromMap(metadata, null);
reference.updateMetadata(md).addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
@Override
public void onSuccess(StorageMetadata storageMetadata) {
WritableMap data = getMetadataAsMap(storageMetadata);
promise.resolve(data);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
promiseRejectStorageException(promise, exception);
}
});
reference
.updateMetadata(md)
.addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
@Override
public void onSuccess(StorageMetadata storageMetadata) {
WritableMap data = getMetadataAsMap(storageMetadata);
promise.resolve(data);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
promiseRejectStorageException(promise, exception);
}
});
}
@ -212,7 +225,12 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#downloadFile
*/
@ReactMethod
public void downloadFile(final String appName, final String path, final String localPath, final Promise promise) {
public void downloadFile(
final String appName,
final String path,
final String localPath,
final Promise promise
) {
if (!isExternalStorageWritable()) {
promise.reject(
"storage/invalid-device-file-path",
@ -225,59 +243,70 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
Log.d(TAG, "downloadFile path: " + path);
StorageReference reference = this.getReference(path, appName);
reference.getStream(new StreamDownloadTask.StreamProcessor() {
@Override
public void doInBackground(StreamDownloadTask.TaskSnapshot taskSnapshot, InputStream inputStream) throws IOException {
int indexOfLastSlash = localPath.lastIndexOf("/");
String pathMinusFileName = indexOfLastSlash > 0 ? localPath.substring(0, indexOfLastSlash) + "/" : "/";
String filename = indexOfLastSlash > 0 ? localPath.substring(indexOfLastSlash + 1) : localPath;
File fileWithJustPath = new File(pathMinusFileName);
reference
.getStream(new StreamDownloadTask.StreamProcessor() {
@Override
public void doInBackground(
StreamDownloadTask.TaskSnapshot taskSnapshot,
InputStream inputStream
) throws IOException {
int indexOfLastSlash = localPath.lastIndexOf("/");
String pathMinusFileName = indexOfLastSlash > 0 ? localPath.substring(
0,
indexOfLastSlash
) + "/" : "/";
String filename = indexOfLastSlash > 0 ? localPath.substring(indexOfLastSlash + 1) : localPath;
File fileWithJustPath = new File(pathMinusFileName);
// directoriesCreated assignment for not consumed warning
Boolean directoriesCreated = fileWithJustPath.mkdirs();
File fileWithFullPath = new File(pathMinusFileName, filename);
FileOutputStream output = new FileOutputStream(fileWithFullPath);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
// directoriesCreated assignment for not consumed warning
Boolean directoriesCreated = fileWithJustPath.mkdirs();
File fileWithFullPath = new File(pathMinusFileName, filename);
FileOutputStream output = new FileOutputStream(fileWithFullPath);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len;
while ((len = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, len);
int len;
while ((len = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, len);
}
output.close();
}
output.close();
}
}).addOnProgressListener(new OnProgressListener<StreamDownloadTask.TaskSnapshot>() {
@Override
public void onProgress(StreamDownloadTask.TaskSnapshot taskSnapshot) {
Log.d(TAG, "downloadFile progress " + taskSnapshot);
WritableMap event = getDownloadTaskAsMap(taskSnapshot);
sendJSEvent(appName, STORAGE_STATE_CHANGED, path, event);
}
}).addOnPausedListener(new OnPausedListener<StreamDownloadTask.TaskSnapshot>() {
@Override
public void onPaused(StreamDownloadTask.TaskSnapshot taskSnapshot) {
Log.d(TAG, "downloadFile paused " + taskSnapshot);
WritableMap event = getDownloadTaskAsMap(taskSnapshot);
sendJSEvent(appName, STORAGE_STATE_CHANGED, path, event);
}
}).addOnSuccessListener(new OnSuccessListener<StreamDownloadTask.TaskSnapshot>() {
@Override
public void onSuccess(StreamDownloadTask.TaskSnapshot taskSnapshot) {
Log.d(TAG, "downloadFile success" + taskSnapshot);
WritableMap resp = getDownloadTaskAsMap(taskSnapshot);
sendJSEvent(appName, STORAGE_DOWNLOAD_SUCCESS, path, resp);
resp = getDownloadTaskAsMap(taskSnapshot);
promise.resolve(resp);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
Log.e(TAG, "downloadFile failure " + exception.getMessage());
// TODO sendJS error event
promiseRejectStorageException(promise, exception);
}
});
})
.addOnProgressListener(new OnProgressListener<StreamDownloadTask.TaskSnapshot>() {
@Override
public void onProgress(StreamDownloadTask.TaskSnapshot taskSnapshot) {
Log.d(TAG, "downloadFile progress " + taskSnapshot);
WritableMap event = getDownloadTaskAsMap(taskSnapshot);
sendJSEvent(appName, STORAGE_STATE_CHANGED, path, event);
}
})
.addOnPausedListener(new OnPausedListener<StreamDownloadTask.TaskSnapshot>() {
@Override
public void onPaused(StreamDownloadTask.TaskSnapshot taskSnapshot) {
Log.d(TAG, "downloadFile paused " + taskSnapshot);
WritableMap event = getDownloadTaskAsMap(taskSnapshot);
sendJSEvent(appName, STORAGE_STATE_CHANGED, path, event);
}
})
.addOnSuccessListener(new OnSuccessListener<StreamDownloadTask.TaskSnapshot>() {
@Override
public void onSuccess(StreamDownloadTask.TaskSnapshot taskSnapshot) {
Log.d(TAG, "downloadFile success" + taskSnapshot);
WritableMap resp = getDownloadTaskAsMap(taskSnapshot);
sendJSEvent(appName, STORAGE_DOWNLOAD_SUCCESS, path, resp);
resp = getDownloadTaskAsMap(taskSnapshot);
promise.resolve(resp);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
Log.e(TAG, "downloadFile failure " + exception.getMessage());
// TODO sendJS error event
promiseRejectStorageException(promise, exception);
}
});
}
/**
@ -332,7 +361,13 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
* @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#putFile
*/
@ReactMethod
public void putFile(final String appName, final String path, final String localPath, final ReadableMap metadata, final Promise promise) {
public void putFile(
final String appName,
final String path,
final String localPath,
final ReadableMap metadata,
final Promise promise
) {
StorageReference reference = this.getReference(path, appName);
Log.i(TAG, "putFile: " + localPath + " to " + path);
@ -436,7 +471,9 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
private Uri getURI(final String uri) {
Uri parsed = Uri.parse(uri);
if (parsed.getScheme() == null || parsed.getScheme().isEmpty()) {
if (parsed.getScheme() == null || parsed
.getScheme()
.isEmpty()) {
return Uri.fromFile(new File(uri));
}
return parsed;
@ -470,14 +507,18 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
} else if (file != null) {
String mimeType = null;
if (file.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
if (file
.getScheme()
.equals(ContentResolver.SCHEME_CONTENT)) {
ContentResolver cr = getReactApplicationContext().getContentResolver();
mimeType = cr.getType(file);
} else {
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(file
.toString());
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
fileExtension.toLowerCase());
.toString());
mimeType = MimeTypeMap
.getSingleton()
.getMimeTypeFromExtension(
fileExtension.toLowerCase());
}
if (mimeType != null) metadataBuilder.setContentType(mimeType);
@ -498,7 +539,12 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
private WritableMap getDownloadTaskAsMap(final StreamDownloadTask.TaskSnapshot taskSnapshot) {
WritableMap resp = Arguments.createMap();
resp.putDouble("bytesTransferred", taskSnapshot.getBytesTransferred());
resp.putString("ref", taskSnapshot.getStorage().getPath());
resp.putString(
"ref",
taskSnapshot
.getStorage()
.getPath()
);
resp.putString("state", this.getTaskStatus(taskSnapshot.getTask()));
resp.putDouble("totalBytes", taskSnapshot.getTotalByteCount());
@ -512,29 +558,40 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
* @param taskSnapshot
* @return
*/
private void getUploadTaskAsMap(final UploadTask.TaskSnapshot taskSnapshot, final OnSuccessListener<WritableMap> listener) {
private void getUploadTaskAsMap(
final UploadTask.TaskSnapshot taskSnapshot,
final OnSuccessListener<WritableMap> listener
) {
if (taskSnapshot != null) {
taskSnapshot.getStorage().getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri downloadUrl) {
WritableMap resp = Arguments.createMap();
taskSnapshot
.getStorage()
.getDownloadUrl()
.addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri downloadUrl) {
WritableMap resp = Arguments.createMap();
resp.putDouble("bytesTransferred", taskSnapshot.getBytesTransferred());
resp.putString("downloadURL", downloadUrl.toString());
resp.putDouble("bytesTransferred", taskSnapshot.getBytesTransferred());
resp.putString("downloadURL", downloadUrl.toString());
StorageMetadata d = taskSnapshot.getMetadata();
if (d != null) {
WritableMap metadata = getMetadataAsMap(d);
resp.putMap("metadata", metadata);
StorageMetadata d = taskSnapshot.getMetadata();
if (d != null) {
WritableMap metadata = getMetadataAsMap(d);
resp.putMap("metadata", metadata);
}
resp.putString(
"ref",
taskSnapshot
.getStorage()
.getPath()
);
resp.putString("state", RNFirebaseStorage.this.getTaskStatus(taskSnapshot.getTask()));
resp.putDouble("totalBytes", taskSnapshot.getTotalByteCount());
listener.onSuccess(resp);
}
resp.putString("ref", taskSnapshot.getStorage().getPath());
resp.putString("state", RNFirebaseStorage.this.getTaskStatus(taskSnapshot.getTask()));
resp.putDouble("totalBytes", taskSnapshot.getTotalByteCount());
listener.onSuccess(resp);
}
});
});
} else {
listener.onSuccess(Arguments.createMap());
}
@ -683,10 +740,33 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(DocumentDirectoryPath, this.getReactApplicationContext().getFilesDir().getAbsolutePath());
constants.put(TemporaryDirectoryPath, this.getReactApplicationContext().getCacheDir().getAbsolutePath());
constants.put(PicturesDirectoryPath, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath());
constants.put(CachesDirectoryPath, this.getReactApplicationContext().getCacheDir().getAbsolutePath());
constants.put(
DocumentDirectoryPath,
this
.getReactApplicationContext()
.getFilesDir()
.getAbsolutePath()
);
constants.put(
TemporaryDirectoryPath,
this
.getReactApplicationContext()
.getCacheDir()
.getAbsolutePath()
);
constants.put(
PicturesDirectoryPath,
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
.getAbsolutePath()
);
constants.put(
CachesDirectoryPath,
this
.getReactApplicationContext()
.getCacheDir()
.getAbsolutePath()
);
constants.put(FileTypeRegular, 0);
constants.put(FileTypeDirectory, 1);
@ -697,7 +777,9 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
constants.put(ExternalStorageDirectoryPath, null);
}
File externalDirectory = this.getReactApplicationContext().getExternalFilesDir(null);
File externalDirectory = this
.getReactApplicationContext()
.getExternalFilesDir(null);
if (externalDirectory != null) {
constants.put(ExternalDirectoryPath, externalDirectory.getAbsolutePath());
} else {