Merge remote-tracking branch 'origin/master'
# Conflicts: # android/src/main/java/io/invertase/firebase/crash/RNFirebaseCrash.java # android/src/main/java/io/invertase/firebase/crash/RNFirebaseCrashPackage.java # lib/index.d.ts
This commit is contained in:
commit
52c63b5e18
|
@ -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()) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,18 +3,24 @@ package io.invertase.firebase.perf;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
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.WritableMap;
|
||||
import com.google.firebase.perf.FirebasePerformance;
|
||||
import com.google.firebase.perf.metrics.Trace;
|
||||
import com.google.firebase.perf.metrics.HttpMetric;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RNFirebasePerformance extends ReactContextBaseJavaModule {
|
||||
|
||||
private static final String TAG = "RNFirebasePerformance";
|
||||
private HashMap<String, Trace> traces = new HashMap<>();
|
||||
private HashMap<String, HttpMetric> httpMetrics = new HashMap<>();
|
||||
|
||||
public RNFirebasePerformance(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
|
@ -30,19 +36,79 @@ public class RNFirebasePerformance extends ReactContextBaseJavaModule {
|
|||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setPerformanceCollectionEnabled(Boolean enabled) {
|
||||
public void setPerformanceCollectionEnabled(Boolean enabled, Promise promise) {
|
||||
FirebasePerformance.getInstance().setPerformanceCollectionEnabled(enabled);
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trace
|
||||
*/
|
||||
|
||||
@ReactMethod
|
||||
public void getTraceAttribute(String identifier, String attribute, Promise promise) {
|
||||
promise.resolve(getOrCreateTrace(identifier).getAttribute(attribute));
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void start(String identifier) {
|
||||
public void getTraceAttributes(String identifier, Promise promise) {
|
||||
Map<String, String> attributes = getOrCreateTrace(identifier).getAttributes();
|
||||
WritableMap map = Arguments.createMap();
|
||||
|
||||
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
||||
map.putString(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
promise.resolve(map);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getTraceLongMetric(String identifier, String metricName, Promise promise) {
|
||||
Integer value = Long.valueOf(getOrCreateTrace(identifier).getLongMetric(metricName)).intValue();
|
||||
promise.resolve(value);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void incrementTraceMetric(String identifier, String metricName, Integer incrementBy, Promise promise) {
|
||||
getOrCreateTrace(identifier).incrementMetric(metricName, incrementBy.longValue());
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void putTraceAttribute(String identifier, String attribute, String value, Promise promise) {
|
||||
getOrCreateTrace(identifier).putAttribute(attribute, value);
|
||||
// Docs say it returns a bool, actually void so we internally check attributes
|
||||
Map<String, String> attributes = getOrCreateTrace(identifier).getAttributes();
|
||||
if (attributes.containsKey(attribute)) {
|
||||
promise.resolve(true);
|
||||
} else {
|
||||
promise.resolve(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void putTraceMetric(String identifier, String metricName, Integer value, Promise promise) {
|
||||
getOrCreateTrace(identifier).putMetric(metricName, value.longValue());
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void removeTraceAttribute(String identifier, String attribute, Promise promise) {
|
||||
getOrCreateTrace(identifier).removeAttribute(attribute);
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void startTrace(String identifier, Promise promise) {
|
||||
getOrCreateTrace(identifier).start();
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void stop(String identifier) {
|
||||
public void stopTrace(String identifier, Promise promise) {
|
||||
getOrCreateTrace(identifier).stop();
|
||||
traces.remove(identifier);
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
|
@ -50,6 +116,86 @@ public class RNFirebasePerformance extends ReactContextBaseJavaModule {
|
|||
getOrCreateTrace(identifier).incrementCounter(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Http Metric
|
||||
*/
|
||||
|
||||
@ReactMethod
|
||||
public void getHttpMetricAttribute(String url, String httpMethod, String attribute, Promise promise) {
|
||||
promise.resolve(getOrCreateHttpMetric(url, httpMethod).getAttribute(attribute));
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getHttpMetricAttributes(String url, String httpMethod, Promise promise) {
|
||||
Map<String, String> attributes = getOrCreateHttpMetric(url, httpMethod).getAttributes();
|
||||
WritableMap map = Arguments.createMap();
|
||||
|
||||
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
||||
map.putString(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
promise.resolve(map);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void putHttpMetricAttribute(String url, String httpMethod, String attribute, String value, Promise promise) {
|
||||
getOrCreateHttpMetric(url, httpMethod).putAttribute(attribute, value);
|
||||
// Docs say it returns a bool, actually void so we internally check attributes
|
||||
Map<String, String> attributes = getOrCreateHttpMetric(url, httpMethod).getAttributes();
|
||||
if (attributes.containsKey(attribute)) {
|
||||
promise.resolve( true);
|
||||
} else {
|
||||
promise.resolve(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void removeHttpMetricAttribute(String url, String httpMethod, String attribute, Promise promise) {
|
||||
getOrCreateHttpMetric(url, httpMethod).removeAttribute(attribute);
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setHttpMetricResponseCode(String url, String httpMethod, Integer code, Promise promise) {
|
||||
getOrCreateHttpMetric(url, httpMethod).setHttpResponseCode(code);
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setHttpMetricRequestPayloadSize(String url, String httpMethod, Integer bytes, Promise promise) {
|
||||
getOrCreateHttpMetric(url, httpMethod).setRequestPayloadSize(bytes.longValue());
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setHttpMetricResponseContentType(String url, String httpMethod, String type, Promise promise) {
|
||||
getOrCreateHttpMetric(url, httpMethod).setResponseContentType(type);
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setHttpMetricResponsePayloadSize(String url, String httpMethod, Integer bytes, Promise promise) {
|
||||
getOrCreateHttpMetric(url, httpMethod).setResponsePayloadSize(bytes.longValue());
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void startHttpMetric(String url, String httpMethod, Promise promise) {
|
||||
getOrCreateHttpMetric(url, httpMethod).start();
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void stopHttpMetric(String url, String httpMethod, Promise promise) {
|
||||
getOrCreateHttpMetric(url, httpMethod).stop();
|
||||
httpMetrics.remove(url + httpMethod);
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private
|
||||
*/
|
||||
|
||||
private Trace getOrCreateTrace(String identifier) {
|
||||
if (traces.containsKey(identifier)) {
|
||||
return traces.get(identifier);
|
||||
|
@ -58,4 +204,39 @@ public class RNFirebasePerformance extends ReactContextBaseJavaModule {
|
|||
traces.put(identifier, trace);
|
||||
return trace;
|
||||
}
|
||||
|
||||
private HttpMetric getOrCreateHttpMetric(String url, String httpMethod) {
|
||||
String identifier = url + httpMethod;
|
||||
if (httpMetrics.containsKey(identifier)) {
|
||||
return httpMetrics.get(identifier);
|
||||
}
|
||||
HttpMetric httpMetric = FirebasePerformance.getInstance().newHttpMetric(url, this.mapStringToMethod(httpMethod));
|
||||
httpMetrics.put(identifier, httpMetric);
|
||||
return httpMetric;
|
||||
}
|
||||
|
||||
private String mapStringToMethod(String value) {
|
||||
switch (value) {
|
||||
case "CONNECT":
|
||||
return FirebasePerformance.HttpMethod.CONNECT;
|
||||
case "DELETE":
|
||||
return FirebasePerformance.HttpMethod.DELETE;
|
||||
case "GET":
|
||||
return FirebasePerformance.HttpMethod.GET;
|
||||
case "HEAD":
|
||||
return FirebasePerformance.HttpMethod.HEAD;
|
||||
case "OPTIONS":
|
||||
return FirebasePerformance.HttpMethod.OPTIONS;
|
||||
case "PATCH":
|
||||
return FirebasePerformance.HttpMethod.PATCH;
|
||||
case "POST":
|
||||
return FirebasePerformance.HttpMethod.POST;
|
||||
case "PUT":
|
||||
return FirebasePerformance.HttpMethod.PUT;
|
||||
case "TRACE":
|
||||
return FirebasePerformance.HttpMethod.TRACE;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -9,7 +9,7 @@ buildscript {
|
|||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.1.3'
|
||||
classpath 'com.google.gms:google-services:4.0.1'
|
||||
classpath 'com.google.firebase:firebase-plugins:1.1.1'
|
||||
classpath 'com.google.firebase:firebase-plugins:1.1.5'
|
||||
classpath 'io.fabric.tools:gradle:1.25.4'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
describe('perf()', () => {
|
||||
describe('HttpMetric', () => {
|
||||
it('start() & stop()', async () => {
|
||||
const httpMetric = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
await httpMetric.start();
|
||||
await httpMetric.stop();
|
||||
});
|
||||
|
||||
it('removeAttribute()', async () => {
|
||||
const httpMetric = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
await httpMetric.start();
|
||||
await httpMetric.putAttribute('foo', 'bar');
|
||||
const value = await httpMetric.getAttribute('foo');
|
||||
should.equal(value, 'bar');
|
||||
await httpMetric.removeAttribute('foo');
|
||||
const value2 = await httpMetric.getAttribute('foo');
|
||||
should.equal(value2, null);
|
||||
await httpMetric.stop();
|
||||
});
|
||||
|
||||
it('getAttribute() should return null', async () => {
|
||||
const httpMetric = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
await httpMetric.start();
|
||||
const value = await httpMetric.getAttribute('foo');
|
||||
should.equal(value, null);
|
||||
await httpMetric.removeAttribute('foo');
|
||||
await httpMetric.stop();
|
||||
});
|
||||
|
||||
it('getAttribute() should return string value', async () => {
|
||||
const httpMetric = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
await httpMetric.start();
|
||||
await httpMetric.putAttribute('foo', 'bar');
|
||||
const value = await httpMetric.getAttribute('foo');
|
||||
should.equal(value, 'bar');
|
||||
await httpMetric.removeAttribute('foo');
|
||||
await httpMetric.stop();
|
||||
});
|
||||
|
||||
it('putAttribute()', async () => {
|
||||
const httpMetric = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
await httpMetric.start();
|
||||
await httpMetric.putAttribute('foo', 'bar');
|
||||
const value = await httpMetric.getAttribute('foo');
|
||||
value.should.equal('bar');
|
||||
await httpMetric.removeAttribute('foo');
|
||||
await httpMetric.stop();
|
||||
});
|
||||
|
||||
it('getAttributes()', async () => {
|
||||
const httpMetric = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
await httpMetric.start();
|
||||
await httpMetric.putAttribute('foo', 'bar');
|
||||
await httpMetric.putAttribute('bar', 'baz');
|
||||
const value = await httpMetric.getAttributes();
|
||||
value.should.deepEqual({
|
||||
foo: 'bar',
|
||||
bar: 'baz',
|
||||
});
|
||||
await httpMetric.removeAttribute('foo');
|
||||
await httpMetric.removeAttribute('bar');
|
||||
await httpMetric.stop();
|
||||
});
|
||||
|
||||
it('setHttpResponseCode()', async () => {
|
||||
const httpMetric = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
await httpMetric.start();
|
||||
await httpMetric.setHttpResponseCode(500);
|
||||
await httpMetric.stop();
|
||||
});
|
||||
|
||||
it('setRequestPayloadSize()', async () => {
|
||||
const httpMetric = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
await httpMetric.start();
|
||||
await httpMetric.setRequestPayloadSize(1234567);
|
||||
await httpMetric.stop();
|
||||
});
|
||||
|
||||
it('setResponseContentType()', async () => {
|
||||
const httpMetric = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
await httpMetric.start();
|
||||
await httpMetric.setResponseContentType('application/foobar');
|
||||
await httpMetric.stop();
|
||||
});
|
||||
|
||||
it('setResponsePayloadSize()', async () => {
|
||||
const httpMetric = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
await httpMetric.start();
|
||||
await httpMetric.setResponsePayloadSize(123456789);
|
||||
await httpMetric.stop();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -8,9 +8,10 @@ describe('perf()', () => {
|
|||
await firebase.perf().setPerformanceCollectionEnabled(false);
|
||||
});
|
||||
|
||||
xit('errors if not boolean', async () => {
|
||||
// TODO add validations to lib
|
||||
await firebase.perf().setPerformanceCollectionEnabled();
|
||||
it('errors if not boolean', async () => {
|
||||
(() => firebase.perf().setPerformanceCollectionEnabled()).should.throw(
|
||||
'firebase.perf().setPerformanceCollectionEnabled() requires a boolean value'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -20,15 +21,27 @@ describe('perf()', () => {
|
|||
trace.constructor.name.should.be.equal('Trace');
|
||||
});
|
||||
|
||||
xit('errors if identifier not a string', async () => {
|
||||
// TODO add validations to lib
|
||||
try {
|
||||
firebase.perf().newTrace([1, 2, 3, 4]);
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
it('errors if identifier not a string', async () => {
|
||||
(() => firebase.perf().newTrace([1, 2, 3, 4])).should.throw(
|
||||
'firebase.perf().newTrace() requires a string value'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
throw new Error('Trace did not error on invalid identifier');
|
||||
describe('newHttpMetric()', () => {
|
||||
it('returns an instance of HttpMetric', async () => {
|
||||
const trace = firebase.perf().newHttpMetric('http://foo.com', 'GET');
|
||||
trace.constructor.name.should.be.equal('HttpMetric');
|
||||
});
|
||||
|
||||
it('errors if url/httpMethod not a string', async () => {
|
||||
(() => firebase.perf().newHttpMetric(123, [1, 2])).should.throw(
|
||||
'firebase.perf().newHttpMetric() requires url and httpMethod string values'
|
||||
);
|
||||
});
|
||||
|
||||
it('errors if httpMethod not a valid type', async () => {
|
||||
(() => firebase.perf().newHttpMetric('foo', 'FOO')).should.throw(); // TODO error
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,23 +6,83 @@ describe('perf()', () => {
|
|||
await trace.stop();
|
||||
});
|
||||
|
||||
describe('incrementCounter()', () => {
|
||||
it('accepts a string event', async () => {
|
||||
const trace = firebase.perf().newTrace('bar');
|
||||
await trace.start();
|
||||
await trace.incrementCounter('fooby');
|
||||
await trace.incrementCounter('fooby');
|
||||
await trace.incrementCounter('fooby');
|
||||
await trace.incrementCounter('fooby');
|
||||
await trace.stop();
|
||||
});
|
||||
|
||||
xit('errors if event is not a string', async () => {
|
||||
const trace = firebase.perf().newTrace('bar');
|
||||
await trace.start();
|
||||
await trace.incrementCounter([1, 2, 3, 4]);
|
||||
await trace.stop();
|
||||
});
|
||||
it('getAttribute() should return null', async () => {
|
||||
const trace = firebase.perf().newTrace('bar');
|
||||
await trace.start();
|
||||
const value = await trace.getAttribute('foo');
|
||||
should.equal(value, null);
|
||||
await trace.stop();
|
||||
});
|
||||
|
||||
it('getAttribute() should return string value', async () => {
|
||||
const trace = firebase.perf().newTrace('bar');
|
||||
await trace.start();
|
||||
await trace.putAttribute('foo', 'bar');
|
||||
const value = await trace.getAttribute('foo');
|
||||
should.equal(value, 'bar');
|
||||
await trace.stop();
|
||||
});
|
||||
|
||||
it('putAttribute()', async () => {
|
||||
const trace = firebase.perf().newTrace('bar');
|
||||
await trace.start();
|
||||
await trace.putAttribute('foo', 'bar');
|
||||
const value = await trace.getAttribute('foo');
|
||||
value.should.equal('bar');
|
||||
await trace.stop();
|
||||
});
|
||||
|
||||
it('getAttributes()', async () => {
|
||||
const trace = firebase.perf().newTrace('bar');
|
||||
await trace.start();
|
||||
await trace.putAttribute('foo', 'bar');
|
||||
await trace.putAttribute('bar', 'baz');
|
||||
const value = await trace.getAttributes();
|
||||
value.should.deepEqual({
|
||||
foo: 'bar',
|
||||
bar: 'baz',
|
||||
});
|
||||
await trace.stop();
|
||||
});
|
||||
|
||||
it('removeAttribute()', async () => {
|
||||
const trace = firebase.perf().newTrace('bar');
|
||||
await trace.start();
|
||||
await trace.putAttribute('foobar', 'bar');
|
||||
const value = await trace.getAttribute('foobar');
|
||||
value.should.equal('bar');
|
||||
await trace.removeAttribute('foobar');
|
||||
const removed = await trace.getAttribute('foobar');
|
||||
should.equal(removed, null);
|
||||
await trace.stop();
|
||||
});
|
||||
|
||||
it('getMetric()', async () => {
|
||||
const trace = firebase.perf().newTrace('bar');
|
||||
await trace.start();
|
||||
const metric = await trace.getMetric('foo');
|
||||
metric.should.equal(0);
|
||||
await trace.stop();
|
||||
});
|
||||
|
||||
it('putMetric()', async () => {
|
||||
const trace = firebase.perf().newTrace('bar');
|
||||
await trace.start();
|
||||
await trace.putMetric('baz', 1);
|
||||
const metric = await trace.getMetric('baz');
|
||||
metric.should.equal(1);
|
||||
await trace.stop();
|
||||
});
|
||||
|
||||
it('incrementMetric()', async () => {
|
||||
const trace = firebase.perf().newTrace('bar');
|
||||
await trace.start();
|
||||
await trace.putMetric('baz', 1);
|
||||
await trace.incrementMetric('baz', 2);
|
||||
const metric = await trace.getMetric('baz');
|
||||
metric.should.equal(3);
|
||||
await trace.stop();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
}
|
||||
|
||||
@property NSMutableDictionary *traces;
|
||||
@property NSMutableDictionary *httpMetrics;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#if __has_include(<FirebasePerformance/FIRPerformance.h>)
|
||||
#import <FirebasePerformance/FIRPerformance.h>
|
||||
#import <FirebasePerformance/FIRHTTPMetric.h>
|
||||
@implementation RNFirebasePerformance
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
|
@ -9,10 +10,25 @@ RCT_EXPORT_MODULE();
|
|||
self = [super init];
|
||||
if (self != nil) {
|
||||
_traces = [[NSMutableDictionary alloc] init];
|
||||
_httpMetrics = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (FIRHTTPMethod) mapStringToMethod:(NSString *) value {
|
||||
if ([value compare:@"get" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodGET;
|
||||
if ([value compare:@"put" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodPUT;
|
||||
if ([value compare:@"post" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodPUT;
|
||||
if ([value compare:@"delete" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodDELETE;
|
||||
if ([value compare:@"head" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodHEAD;
|
||||
if ([value compare:@"patch" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodPATCH;
|
||||
if ([value compare:@"options" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodOPTIONS;
|
||||
if ([value compare:@"trace" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodTRACE;
|
||||
if ([value compare:@"connect" options:NSCaseInsensitiveSearch] == NSOrderedSame) return FIRHTTPMethodCONNECT;
|
||||
return FIRHTTPMethodGET;
|
||||
}
|
||||
|
||||
|
||||
- (FIRTrace *)getOrCreateTrace:(NSString *)identifier {
|
||||
if (_traces[identifier]) {
|
||||
return _traces[identifier];
|
||||
|
@ -22,27 +38,223 @@ RCT_EXPORT_MODULE();
|
|||
return trace;
|
||||
}
|
||||
|
||||
- (FIRHTTPMetric *)getOrCreateHttpMetric:(NSString *)url httpMethod:(NSString *) httpMethod {
|
||||
NSString *identifier = [NSString stringWithFormat:@"%@%@", url, httpMethod];
|
||||
if (_httpMetrics[identifier]) {
|
||||
return _httpMetrics[identifier];
|
||||
}
|
||||
NSURL * toURL = [NSURL URLWithString:url];
|
||||
FIRHTTPMethod method = [self mapStringToMethod:httpMethod];
|
||||
FIRHTTPMetric *httpMetric = [[FIRHTTPMetric alloc] initWithURL:toURL HTTPMethod:method];
|
||||
_httpMetrics[identifier] = httpMetric;
|
||||
return httpMetric;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setPerformanceCollectionEnabled:
|
||||
(BOOL *) enabled) {
|
||||
[FIRPerformance sharedInstance].dataCollectionEnabled = (BOOL) enabled;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(start:
|
||||
(NSString *) identifier) {
|
||||
/**
|
||||
* Trace
|
||||
*/
|
||||
|
||||
RCT_EXPORT_METHOD(startTrace:
|
||||
(NSString *) identifier
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[self getOrCreateTrace:identifier] start];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(stop:
|
||||
(NSString *) identifier) {
|
||||
RCT_EXPORT_METHOD(stopTrace:
|
||||
(NSString *) identifier
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[self getOrCreateTrace:identifier] stop];
|
||||
_traces[identifier] = nil;
|
||||
[_traces removeObjectForKey:identifier];
|
||||
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(incrementCounter:
|
||||
(NSString *) identifier
|
||||
event:
|
||||
(NSString *) event) {
|
||||
[[self getOrCreateTrace:identifier] incrementCounterNamed:event];
|
||||
RCT_EXPORT_METHOD(getTraceAttribute:
|
||||
(NSString *) identifier
|
||||
attribute:(NSString *) attribute
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
NSString *value = [[self getOrCreateTrace:identifier] valueForAttribute:attribute];
|
||||
resolve(value ? value : [NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getTraceAttributes:
|
||||
(NSString *) identifier
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
resolve([[self getOrCreateTrace:identifier] attributes]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getTraceLongMetric:
|
||||
(NSString *) identifier
|
||||
metricName:(NSString *) metricName
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
int64_t value = [[self getOrCreateTrace:identifier] valueForIntMetric:metricName];
|
||||
resolve(@(value));
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(incrementTraceMetric:
|
||||
(NSString *) identifier
|
||||
metricName:(NSString *) metricName
|
||||
incrementBy:(NSNumber *) incrementBy
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
int64_t byInt = [incrementBy intValue];
|
||||
[[self getOrCreateTrace:identifier] incrementMetric:metricName byInt:byInt];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(putTraceAttribute:
|
||||
(NSString *) identifier
|
||||
attribute:(NSString *) attribute
|
||||
value:(NSString *) value
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
FIRTrace * trace = [self getOrCreateTrace:identifier];
|
||||
[trace setValue:value forAttribute:attribute];
|
||||
|
||||
if (trace.attributes[attribute] != nil) {
|
||||
resolve(@(YES));
|
||||
} else {
|
||||
resolve(@(NO));
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(putTraceMetric:
|
||||
(NSString *) identifier
|
||||
attribute:(NSString *) attribute
|
||||
value:(NSNumber *) value
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
int64_t byInt = [value intValue];
|
||||
[[self getOrCreateTrace:identifier] setIntValue:byInt forMetric:attribute];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(removeTraceAttribute:
|
||||
(NSString *) identifier
|
||||
attribute:(NSString *) attribute
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[self getOrCreateTrace:identifier] removeAttribute:attribute];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP Metric
|
||||
*/
|
||||
|
||||
RCT_EXPORT_METHOD(startHttpMetric:
|
||||
(NSString *) url
|
||||
httpMethod:(NSString *) httpMethod
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[self getOrCreateHttpMetric:url httpMethod:httpMethod] start];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(stopHttpMetric:
|
||||
(NSString *) url
|
||||
httpMethod:(NSString *) httpMethod
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[self getOrCreateHttpMetric:url httpMethod:httpMethod] stop];
|
||||
[_httpMetrics removeObjectForKey:[NSString stringWithFormat:@"%@%@", url, httpMethod]];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getHttpMetricAttribute:
|
||||
(NSString *) url
|
||||
httpMethod:(NSString *) httpMethod
|
||||
attribute:(NSString *) attribute
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
NSString *value = [[self getOrCreateHttpMetric:url httpMethod:httpMethod] valueForAttribute:attribute];
|
||||
resolve(value ? value : [NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getHttpMetricAttributes:
|
||||
(NSString *) url
|
||||
httpMethod:(NSString *) httpMethod
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
resolve([[self getOrCreateHttpMetric:url httpMethod:httpMethod] attributes]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(putHttpMetricAttribute:
|
||||
(NSString *) url
|
||||
httpMethod:(NSString *) httpMethod
|
||||
attribute:(NSString *) attribute
|
||||
value:(NSString *) value
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
FIRHTTPMetric * httpMetric = [self getOrCreateHttpMetric:url httpMethod:httpMethod];
|
||||
[httpMetric setValue:value forAttribute:attribute];
|
||||
|
||||
if (httpMetric.attributes[attribute] != nil) {
|
||||
resolve(@(YES));
|
||||
} else {
|
||||
resolve(@(NO));
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(removeHttpMetricAttribute:
|
||||
(NSString *) url
|
||||
httpMethod:(NSString *) httpMethod
|
||||
attribute:(NSString *) attribute
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[self getOrCreateHttpMetric:url httpMethod:httpMethod] removeAttribute:attribute];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setHttpMetricResponseCode:
|
||||
(NSString *) url
|
||||
httpMethod:(NSString *) httpMethod
|
||||
code:(NSNumber *) code
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[self getOrCreateHttpMetric:url httpMethod:httpMethod] setResponseCode:[code integerValue]];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setHttpMetricRequestPayloadSize:
|
||||
(NSString *) url
|
||||
httpMethod:(NSString *) httpMethod
|
||||
bytes:(NSNumber *) bytes
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[self getOrCreateHttpMetric:url httpMethod:httpMethod] setRequestPayloadSize:[bytes longLongValue]];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setHttpMetricResponseContentType:
|
||||
(NSString *) url
|
||||
httpMethod:(NSString *) httpMethod
|
||||
type:(NSString *) type
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[self getOrCreateHttpMetric:url httpMethod:httpMethod] setResponseContentType:type];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setHttpMetricResponsePayloadSize:
|
||||
(NSString *) url
|
||||
httpMethod:(NSString *) httpMethod
|
||||
bytes:(NSNumber *) bytes
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[self getOrCreateHttpMetric:url httpMethod:httpMethod] setResponsePayloadSize:[bytes longLongValue]];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup
|
||||
|
|
|
@ -53,7 +53,7 @@ declare module 'react-native-firebase' {
|
|||
RNFirebase.notifications.Notifications,
|
||||
RNFirebase.notifications.NotificationsStatics
|
||||
>;
|
||||
// perf: FirebaseModuleAndStatics<RNFirebase.perf.Perf>;
|
||||
perf: FirebaseModuleAndStatics<RNFirebase.perf.Perf>;
|
||||
storage: FirebaseModuleAndStatics<RNFirebase.storage.Storage>;
|
||||
// utils: FirebaseModuleAndStatics<RNFirebase.utils.Utils>;
|
||||
initializeApp(options: Firebase.Options, name: string): App;
|
||||
|
@ -90,7 +90,7 @@ declare module 'react-native-firebase' {
|
|||
links(): RNFirebase.links.Links;
|
||||
messaging(): RNFirebase.messaging.Messaging;
|
||||
notifications(): RNFirebase.notifications.Notifications;
|
||||
// perf(): RNFirebase.perf.Performance;
|
||||
perf(): RNFirebase.perf.Perf;
|
||||
storage(): RNFirebase.storage.Storage;
|
||||
// utils(): RNFirebase.utils.Utils;
|
||||
readonly name: string;
|
||||
|
@ -1546,6 +1546,135 @@ declare module 'react-native-firebase' {
|
|||
}
|
||||
}
|
||||
|
||||
namespace perf {
|
||||
type HttpMethod =
|
||||
| 'CONNECT'
|
||||
| 'DELETE'
|
||||
| 'GET'
|
||||
| 'HEAD'
|
||||
| 'OPTIONS'
|
||||
| 'PATCH'
|
||||
| 'POST'
|
||||
| 'PUT'
|
||||
| 'TRACE';
|
||||
|
||||
interface Perf {
|
||||
/**
|
||||
* Globally enable or disable performance monitoring.
|
||||
*/
|
||||
setPerformanceCollectionEnabled(enabled: boolean): void;
|
||||
|
||||
/**
|
||||
* Returns a new Trace instance.
|
||||
*/
|
||||
newTrace(trace: string): Trace;
|
||||
|
||||
/**
|
||||
* Returns a new HTTP Metric instance.
|
||||
*/
|
||||
newHttpMetric(url: string, httpMethod: HttpMethod): HttpMetric;
|
||||
}
|
||||
|
||||
interface Trace {
|
||||
/**
|
||||
* Return an attribute by name, or null if it does not exist.
|
||||
*/
|
||||
getAttribute(attribute: string): Promise<string | null>;
|
||||
|
||||
/**
|
||||
* Return an object of key-value attributes.
|
||||
*/
|
||||
getAttributes(): Promise<Object>;
|
||||
|
||||
/**
|
||||
* Get a metric by name. Returns 0 if it does not exist.
|
||||
*/
|
||||
getMetric(metricName: string): Promise<number>;
|
||||
|
||||
/**
|
||||
* Increment a metric by name and value.
|
||||
*/
|
||||
incrementMetric(metricName: string, incrementBy: number): Promise<null>;
|
||||
|
||||
/**
|
||||
* Set an attribute. Returns true if it was set, false if it was not.
|
||||
*/
|
||||
putAttribute(attribute: string, value: string): Promise<true | false>;
|
||||
|
||||
/**
|
||||
* Set a metric.
|
||||
*/
|
||||
putMetric(metricName: string, value: number): Promise<null>;
|
||||
|
||||
/**
|
||||
* Remove an attribute by name.
|
||||
*/
|
||||
removeAttribute(attribute: string): Promise<null>;
|
||||
|
||||
/**
|
||||
* Start a Trace instance.
|
||||
*/
|
||||
start(): Promise<null>;
|
||||
|
||||
/**
|
||||
* Stop a Trace instance.
|
||||
*/
|
||||
stop(): Promise<null>;
|
||||
}
|
||||
|
||||
interface HttpMetric {
|
||||
/**
|
||||
* Return an attribute by name, or null if it does not exist.
|
||||
*/
|
||||
getAttribute(attribute: string): Promise<string | null>;
|
||||
|
||||
/**
|
||||
* Return an object of key-value attributes.
|
||||
*/
|
||||
getAttributes(): Promise<Object>
|
||||
|
||||
/**
|
||||
* Set an attribute. Returns true if it was set, false if it was not.
|
||||
*/
|
||||
putAttribute(attribute: string, value: string): Promise<true | false>;
|
||||
|
||||
/**
|
||||
* Remove an attribute by name.
|
||||
*/
|
||||
removeAttribute(attribute: string): Promise<null>;
|
||||
|
||||
/**
|
||||
* Set the request HTTP response code.
|
||||
*/
|
||||
setHttpResponseCode(code: number): Promise<null>;
|
||||
|
||||
/**
|
||||
* Set the request payload size, in bytes.
|
||||
*/
|
||||
setRequestPayloadSize(bytes: number): Promise<null>;
|
||||
|
||||
/**
|
||||
* Set the response content type.
|
||||
*/
|
||||
setResponseContentType(type: string): Promise<null>;
|
||||
|
||||
/**
|
||||
* Set the response payload size, in bytes.
|
||||
*/
|
||||
setResponsePayloadSize(bytes: number): Promise<null>;
|
||||
|
||||
/**
|
||||
* Start a HttpMetric instance.
|
||||
*/
|
||||
start(): Promise<null>;
|
||||
|
||||
/**
|
||||
* Stop a HttpMetric instance.
|
||||
*/
|
||||
stop(): Promise<null>;
|
||||
}
|
||||
}
|
||||
|
||||
namespace crashlytics {
|
||||
interface Crashlytics {
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
* @flow
|
||||
* Trace representation wrapper
|
||||
*/
|
||||
import { getNativeModule } from '../../utils/native';
|
||||
import type PerformanceMonitoring from './';
|
||||
|
||||
export default class HttpMetric {
|
||||
url: string;
|
||||
httpMethod: string;
|
||||
_perf: PerformanceMonitoring;
|
||||
|
||||
constructor(perf: PerformanceMonitoring, url: string, httpMethod: string) {
|
||||
this._perf = perf;
|
||||
this.url = url;
|
||||
this.httpMethod = httpMethod;
|
||||
}
|
||||
|
||||
getAttribute(attribute: string): Promise<string | null> {
|
||||
return getNativeModule(this._perf).getHttpMetricAttribute(
|
||||
this.url,
|
||||
this.httpMethod,
|
||||
attribute
|
||||
);
|
||||
}
|
||||
|
||||
getAttributes(): Promise<Object> {
|
||||
return getNativeModule(this._perf).getHttpMetricAttributes(
|
||||
this.url,
|
||||
this.httpMethod
|
||||
);
|
||||
}
|
||||
|
||||
putAttribute(attribute: string, value: string): Promise<true | false> {
|
||||
return getNativeModule(this._perf).putHttpMetricAttribute(
|
||||
this.url,
|
||||
this.httpMethod,
|
||||
attribute,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
removeAttribute(attribute: string): Promise<null> {
|
||||
return getNativeModule(this._perf).removeHttpMetricAttribute(
|
||||
this.url,
|
||||
this.httpMethod,
|
||||
attribute
|
||||
);
|
||||
}
|
||||
|
||||
setHttpResponseCode(code: number): Promise<null> {
|
||||
return getNativeModule(this._perf).setHttpMetricResponseCode(
|
||||
this.url,
|
||||
this.httpMethod,
|
||||
code
|
||||
);
|
||||
}
|
||||
|
||||
setRequestPayloadSize(bytes: number): Promise<null> {
|
||||
return getNativeModule(this._perf).setHttpMetricRequestPayloadSize(
|
||||
this.url,
|
||||
this.httpMethod,
|
||||
bytes
|
||||
);
|
||||
}
|
||||
|
||||
setResponseContentType(type: string): Promise<null> {
|
||||
return getNativeModule(this._perf).setHttpMetricResponseContentType(
|
||||
this.url,
|
||||
this.httpMethod,
|
||||
type
|
||||
);
|
||||
}
|
||||
|
||||
setResponsePayloadSize(bytes: number): Promise<null> {
|
||||
return getNativeModule(this._perf).setHttpMetricResponsePayloadSize(
|
||||
this.url,
|
||||
this.httpMethod,
|
||||
bytes
|
||||
);
|
||||
}
|
||||
|
||||
start(): Promise<null> {
|
||||
return getNativeModule(this._perf).startHttpMetric(
|
||||
this.url,
|
||||
this.httpMethod
|
||||
);
|
||||
}
|
||||
|
||||
stop(): Promise<null> {
|
||||
return getNativeModule(this._perf).stopHttpMetric(
|
||||
this.url,
|
||||
this.httpMethod
|
||||
);
|
||||
}
|
||||
}
|
|
@ -14,15 +14,60 @@ export default class Trace {
|
|||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
start(): void {
|
||||
getNativeModule(this._perf).start(this.identifier);
|
||||
getAttribute(attribute: string): Promise<string | null> {
|
||||
return getNativeModule(this._perf).getTraceAttribute(
|
||||
this.identifier,
|
||||
attribute
|
||||
);
|
||||
}
|
||||
|
||||
stop(): void {
|
||||
getNativeModule(this._perf).stop(this.identifier);
|
||||
getAttributes(): Promise<Object> {
|
||||
return getNativeModule(this._perf).getTraceAttributes(this.identifier);
|
||||
}
|
||||
|
||||
incrementCounter(event: string): void {
|
||||
getNativeModule(this._perf).incrementCounter(this.identifier, event);
|
||||
getMetric(metricName: string): Promise<number> {
|
||||
return getNativeModule(this._perf).getTraceLongMetric(
|
||||
this.identifier,
|
||||
metricName
|
||||
);
|
||||
}
|
||||
|
||||
incrementMetric(metricName: string, incrementBy: number): Promise<null> {
|
||||
return getNativeModule(this._perf).incrementTraceMetric(
|
||||
this.identifier,
|
||||
metricName,
|
||||
incrementBy
|
||||
);
|
||||
}
|
||||
|
||||
putAttribute(attribute: string, value: string): Promise<true | false> {
|
||||
return getNativeModule(this._perf).putTraceAttribute(
|
||||
this.identifier,
|
||||
attribute,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
putMetric(metricName: string, value: number): Promise<null> {
|
||||
return getNativeModule(this._perf).putTraceMetric(
|
||||
this.identifier,
|
||||
metricName,
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
removeAttribute(attribute: string): Promise<null> {
|
||||
return getNativeModule(this._perf).removeTraceAttribute(
|
||||
this.identifier,
|
||||
attribute
|
||||
);
|
||||
}
|
||||
|
||||
start(): Promise<null> {
|
||||
return getNativeModule(this._perf).startTrace(this.identifier);
|
||||
}
|
||||
|
||||
stop(): Promise<null> {
|
||||
return getNativeModule(this._perf).stopTrace(this.identifier);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Performance monitoring representation wrapper
|
||||
*/
|
||||
import Trace from './Trace';
|
||||
import HttpMetric from './HttpMetric';
|
||||
import ModuleBase from '../../utils/ModuleBase';
|
||||
import { getNativeModule } from '../../utils/native';
|
||||
|
||||
|
@ -11,6 +12,29 @@ import type App from '../core/app';
|
|||
export const MODULE_NAME = 'RNFirebasePerformance';
|
||||
export const NAMESPACE = 'perf';
|
||||
|
||||
const HTTP_METHODS = {
|
||||
CONNECT: true,
|
||||
DELETE: true,
|
||||
GET: true,
|
||||
HEAD: true,
|
||||
OPTIONS: true,
|
||||
PATCH: true,
|
||||
POST: true,
|
||||
PUT: true,
|
||||
TRACE: true,
|
||||
};
|
||||
|
||||
type HttpMethod =
|
||||
| 'CONNECT'
|
||||
| 'DELETE'
|
||||
| 'GET'
|
||||
| 'HEAD'
|
||||
| 'OPTIONS'
|
||||
| 'PATCH'
|
||||
| 'POST'
|
||||
| 'PUT'
|
||||
| 'TRACE';
|
||||
|
||||
export default class PerformanceMonitoring extends ModuleBase {
|
||||
constructor(app: App) {
|
||||
super(app, {
|
||||
|
@ -27,7 +51,13 @@ export default class PerformanceMonitoring extends ModuleBase {
|
|||
* @returns {*}
|
||||
*/
|
||||
setPerformanceCollectionEnabled(enabled: boolean): void {
|
||||
getNativeModule(this).setPerformanceCollectionEnabled(enabled);
|
||||
if (typeof enabled !== 'boolean') {
|
||||
throw new Error(
|
||||
'firebase.perf().setPerformanceCollectionEnabled() requires a boolean value'
|
||||
);
|
||||
}
|
||||
|
||||
return getNativeModule(this).setPerformanceCollectionEnabled(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,8 +65,36 @@ export default class PerformanceMonitoring extends ModuleBase {
|
|||
* @param trace
|
||||
*/
|
||||
newTrace(trace: string): Trace {
|
||||
if (typeof trace !== 'string') {
|
||||
throw new Error('firebase.perf().newTrace() requires a string value');
|
||||
}
|
||||
|
||||
return new Trace(this, trace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new HttpMetric instance
|
||||
* @param url
|
||||
* @param httpMethod
|
||||
* @returns {HttpMetric}
|
||||
*/
|
||||
newHttpMetric(url: string, httpMethod: HttpMethod): HttpMetric {
|
||||
if (typeof url !== 'string' || typeof httpMethod !== 'string') {
|
||||
throw new Error(
|
||||
'firebase.perf().newHttpMetric() requires url and httpMethod string values'
|
||||
);
|
||||
}
|
||||
|
||||
if (!HTTP_METHODS[httpMethod]) {
|
||||
throw new Error(
|
||||
`firebase.perf().newHttpMetric() httpMethod should be one of ${Object.keys(
|
||||
HTTP_METHODS
|
||||
).join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
return new HttpMetric(this, url, httpMethod);
|
||||
}
|
||||
}
|
||||
|
||||
export const statics = {};
|
||||
|
|
Loading…
Reference in New Issue