[fcm] Android instanceid and core fcm support; iOS instance and basic fcm support
This commit is contained in:
parent
d429db7e86
commit
850f04914f
|
@ -82,7 +82,7 @@ rootProject.gradle.buildFinished { buildResult ->
|
|||
dependencies {
|
||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||
compile "com.facebook.react:react-native:+" // From node_modules
|
||||
compile 'me.leolin:ShortcutBadger:1.1.18@aar'
|
||||
compile 'me.leolin:ShortcutBadger:1.1.21@aar'
|
||||
compile "com.google.android.gms:play-services-base:$firebaseVersion"
|
||||
compile "com.google.firebase:firebase-core:$firebaseVersion"
|
||||
compile "com.google.firebase:firebase-config:$firebaseVersion"
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package io.invertase.firebase.instanceid;
|
||||
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
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.google.firebase.iid.FirebaseInstanceId;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class RNFirebaseInstanceId extends ReactContextBaseJavaModule {
|
||||
|
||||
private static final String TAG = "RNFirebaseInstanceId";
|
||||
|
||||
public RNFirebaseInstanceId(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
Log.d(TAG, "New instance");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void delete(Promise promise){
|
||||
try {
|
||||
Log.d(TAG, "Deleting instance id");
|
||||
FirebaseInstanceId.getInstance().deleteInstanceId();
|
||||
promise.resolve(null);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
promise.reject("instance_id_error", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void get(Promise promise){
|
||||
String id = FirebaseInstanceId.getInstance().getId();
|
||||
promise.resolve(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package io.invertase.firebase.instanceid;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class RNFirebaseInstanceIdPackage implements ReactPackage {
|
||||
public RNFirebaseInstanceIdPackage() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reactContext react application context that can be used to create modules
|
||||
* @return list of native modules to register with the newly created catalyst instance
|
||||
*/
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
modules.add(new RNFirebaseInstanceId(reactContext));
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param reactContext
|
||||
* @return a list of view managers that should be registered with {@link UIManagerModule}
|
||||
*/
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package io.invertase.firebase.messaging;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
|
||||
import me.leolin.shortcutbadger.ShortcutBadger;
|
||||
|
||||
public class BadgeHelper {
|
||||
|
||||
private static final String TAG = "BadgeHelper";
|
||||
private static final String PREFERENCES_FILE = "BadgeCountFile";
|
||||
private static final String BADGE_COUNT_KEY = "BadgeCount";
|
||||
|
||||
private Context mContext;
|
||||
private SharedPreferences sharedPreferences = null;
|
||||
|
||||
public BadgeHelper(Context context) {
|
||||
mContext = context;
|
||||
sharedPreferences = (SharedPreferences) mContext.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public int getBadgeCount() {
|
||||
return sharedPreferences.getInt(BADGE_COUNT_KEY, 0);
|
||||
}
|
||||
|
||||
public void setBadgeCount(int badgeCount) {
|
||||
storeBadgeCount(badgeCount);
|
||||
if (badgeCount == 0) {
|
||||
ShortcutBadger.removeCount(mContext);
|
||||
Log.d(TAG, "Remove count");
|
||||
} else {
|
||||
ShortcutBadger.applyCount(mContext, badgeCount);
|
||||
Log.d(TAG, "Apply count: " + badgeCount);
|
||||
}
|
||||
}
|
||||
|
||||
private void storeBadgeCount(int badgeCount) {
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putInt(BADGE_COUNT_KEY, badgeCount);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package io.invertase.firebase.messaging;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.firebase.iid.FirebaseInstanceId;
|
||||
import com.google.firebase.iid.FirebaseInstanceIdService;
|
||||
|
||||
public class InstanceIdService extends FirebaseInstanceIdService {
|
||||
|
||||
private static final String TAG = "InstanceIdService";
|
||||
|
||||
/**
|
||||
* Called if InstanceID token is updated. This may occur if the security of
|
||||
* the previous token had been compromised. This call is initiated by the
|
||||
* InstanceID provider.
|
||||
*/
|
||||
@Override
|
||||
public void onTokenRefresh() {
|
||||
// Get updated InstanceID token.
|
||||
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
|
||||
Log.d(TAG, "Refreshed token: " + refreshedToken);
|
||||
|
||||
// Broadcast refreshed token
|
||||
Intent i = new Intent("io.invertase.firebase.messaging.FCMRefreshToken");
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("token", refreshedToken);
|
||||
i.putExtras(bundle);
|
||||
sendBroadcast(i);
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package io.invertase.firebase.messaging;
|
||||
|
||||
import java.util.Map;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||
import com.google.firebase.messaging.RemoteMessage;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class MessagingService extends FirebaseMessagingService {
|
||||
|
||||
private static final String TAG = "MessagingService";
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(RemoteMessage remoteMessage) {
|
||||
Log.d(TAG, "Remote message received");
|
||||
Intent i = new Intent("io.invertase.firebase.messaging.ReceiveNotification");
|
||||
i.putExtra("data", remoteMessage);
|
||||
handleBadge(remoteMessage);
|
||||
buildLocalNotification(remoteMessage);
|
||||
sendOrderedBroadcast(i, null);
|
||||
}
|
||||
|
||||
private void handleBadge(RemoteMessage remoteMessage) {
|
||||
BadgeHelper badgeHelper = new BadgeHelper(this);
|
||||
if (remoteMessage.getData() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map data = remoteMessage.getData();
|
||||
if (data.get("badge") == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int badgeCount = Integer.parseInt((String)data.get("badge"));
|
||||
badgeHelper.setBadgeCount(badgeCount);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Badge count needs to be an integer", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildLocalNotification(RemoteMessage remoteMessage) {
|
||||
if(remoteMessage.getData() == null){
|
||||
return;
|
||||
}
|
||||
Map<String, String> data = remoteMessage.getData();
|
||||
String customNotification = data.get("custom_notification");
|
||||
if(customNotification != null){
|
||||
try {
|
||||
Bundle bundle = BundleJSONConverter.convertToBundle(new JSONObject(customNotification));
|
||||
RNFirebaseLocalMessagingHelper helper = new RNFirebaseLocalMessagingHelper(this.getApplication());
|
||||
helper.sendNotification(bundle);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package io.invertase.firebase.messaging;
|
||||
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
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";
|
||||
|
||||
@Override
|
||||
public void onTokenRefresh() {
|
||||
Log.d(TAG, "onTokenRefresh event received");
|
||||
|
||||
// Build an Intent to pass the token to the RN Application
|
||||
Intent tokenRefreshEvent = new Intent(TOKEN_REFRESH_EVENT);
|
||||
|
||||
// Broadcast it so it is only available to the RN Application
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(tokenRefreshEvent);
|
||||
}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
package io.invertase.firebase.messaging;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.bridge.ActivityEventListener;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
|
@ -26,26 +26,33 @@ import com.google.firebase.messaging.RemoteMessage;
|
|||
import com.google.firebase.messaging.RemoteMessage.Notification;
|
||||
|
||||
import io.invertase.firebase.Utils;
|
||||
import me.leolin.shortcutbadger.ShortcutBadger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class RNFirebaseMessaging extends ReactContextBaseJavaModule implements LifecycleEventListener, ActivityEventListener {
|
||||
private final static String TAG = RNFirebaseMessaging.class.getCanonicalName();
|
||||
private RNFirebaseLocalMessagingHelper mRNFirebaseLocalMessagingHelper;
|
||||
private BadgeHelper mBadgeHelper;
|
||||
public class RNFirebaseMessaging extends ReactContextBaseJavaModule implements ActivityEventListener {
|
||||
private static final String BADGE_FILE = "BadgeCountFile";
|
||||
private static final String BADGE_KEY = "BadgeCount";
|
||||
|
||||
public RNFirebaseMessaging(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
mRNFirebaseLocalMessagingHelper = new RNFirebaseLocalMessagingHelper((Application) reactContext.getApplicationContext());
|
||||
mBadgeHelper = new BadgeHelper(reactContext.getApplicationContext());
|
||||
getReactApplicationContext().addLifecycleEventListener(this);
|
||||
getReactApplicationContext().addActivityEventListener(this);
|
||||
registerTokenRefreshHandler();
|
||||
registerMessageHandler();
|
||||
registerLocalMessageHandler();
|
||||
private static final String TAG = RNFirebaseMessaging.class.getCanonicalName();
|
||||
|
||||
private SharedPreferences sharedPreferences = null;
|
||||
|
||||
public RNFirebaseMessaging(ReactApplicationContext context) {
|
||||
super(context);
|
||||
context.addActivityEventListener(this);
|
||||
|
||||
sharedPreferences = context.getSharedPreferences(BADGE_FILE, Context.MODE_PRIVATE);
|
||||
|
||||
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
|
||||
|
||||
// Subscribe to message events
|
||||
localBroadcastManager.registerReceiver(new MessageReceiver(),
|
||||
new IntentFilter(RNFirebaseMessagingService.MESSAGE_EVENT));
|
||||
|
||||
// Subscribe to token refresh events
|
||||
localBroadcastManager.registerReceiver(new RefreshTokenReceiver(),
|
||||
new IntentFilter(RNFirebaseInstanceIdService.TOKEN_REFRESH_EVENT));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,73 +61,84 @@ public class RNFirebaseMessaging extends ReactContextBaseJavaModule implements L
|
|||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getInitialNotification(Promise promise) {
|
||||
Activity activity = getCurrentActivity();
|
||||
if (activity == null) {
|
||||
public void getToken(Promise promise) {
|
||||
String token = FirebaseInstanceId.getInstance().getToken();
|
||||
Log.d(TAG, "Firebase token: " + token);
|
||||
promise.resolve(token);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void requestPermission(Promise promise) {
|
||||
// TODO: Object structure?
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
// Non Web SDK methods
|
||||
|
||||
@ReactMethod
|
||||
public void getBadge(Promise promise) {
|
||||
int badge = sharedPreferences.getInt(BADGE_KEY, 0);
|
||||
Log.d(TAG, "Got badge count: " + badge);
|
||||
promise.resolve(badge);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getInitialMessage(Promise promise) {
|
||||
if (getCurrentActivity() == null) {
|
||||
promise.resolve(null);
|
||||
} else {
|
||||
WritableMap messageMap = parseIntentForMessage(getCurrentActivity().getIntent());
|
||||
promise.resolve(messageMap);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void sendMessage(ReadableMap messageMap, Promise promise) {
|
||||
if (!messageMap.hasKey("to")) {
|
||||
promise.reject("messaging/invalid-message", "The supplied message is missing a 'to' field");
|
||||
return;
|
||||
}
|
||||
promise.resolve(parseIntent(getCurrentActivity().getIntent()));
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void requestPermissions() {
|
||||
}
|
||||
RemoteMessage.Builder mb = new RemoteMessage.Builder(messageMap.getString("to"));
|
||||
|
||||
@ReactMethod
|
||||
public void getToken(Promise promise) {
|
||||
Log.d(TAG, "Firebase token: " + FirebaseInstanceId.getInstance().getToken());
|
||||
promise.resolve(FirebaseInstanceId.getInstance().getToken());
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void deleteInstanceId(Promise promise){
|
||||
try {
|
||||
Log.d(TAG, "Deleting instance id");
|
||||
FirebaseInstanceId.getInstance().deleteInstanceId();
|
||||
promise.resolve(null);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
promise.reject(null, e.getMessage());
|
||||
if (messageMap.hasKey("collapseKey")) {
|
||||
mb = mb.setCollapseKey(messageMap.getString("collapseKey"));
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void createLocalNotification(ReadableMap details) {
|
||||
Bundle bundle = Arguments.toBundle(details);
|
||||
mRNFirebaseLocalMessagingHelper.sendNotification(bundle);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void scheduleLocalNotification(ReadableMap details) {
|
||||
Bundle bundle = Arguments.toBundle(details);
|
||||
mRNFirebaseLocalMessagingHelper.sendNotificationScheduled(bundle);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void cancelLocalNotification(String notificationID) {
|
||||
mRNFirebaseLocalMessagingHelper.cancelLocalNotification(notificationID);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void cancelAllLocalNotifications() {
|
||||
try {
|
||||
mRNFirebaseLocalMessagingHelper.cancelAllLocalNotifications();
|
||||
} catch (SecurityException e) {
|
||||
// In some devices/situations cancelAllLocalNotifications will throw a SecurityException
|
||||
// We can safely ignore this error for now as the UX impact of this not working is minor.
|
||||
Log.w(TAG, e.getMessage());
|
||||
if (messageMap.hasKey("messageId")) {
|
||||
mb = mb.setMessageId(messageMap.getString("messageId"));
|
||||
}
|
||||
if (messageMap.hasKey("messageType")) {
|
||||
mb = mb.setMessageType(messageMap.getString("messageType"));
|
||||
}
|
||||
if (messageMap.hasKey("ttl")) {
|
||||
mb = mb.setTtl(messageMap.getInt("ttl"));
|
||||
}
|
||||
if (messageMap.hasKey("data")) {
|
||||
ReadableMap dataMap = messageMap.getMap("data");
|
||||
ReadableMapKeySetIterator iterator = dataMap.keySetIterator();
|
||||
while (iterator.hasNextKey()) {
|
||||
String key = iterator.nextKey();
|
||||
mb = mb.addData(key, dataMap.getString(key));
|
||||
}
|
||||
}
|
||||
|
||||
FirebaseMessaging.getInstance().send(mb.build());
|
||||
|
||||
// TODO: Listen to onMessageSent and onSendError for better feedback?
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void removeDeliveredNotification(String notificationID) {
|
||||
mRNFirebaseLocalMessagingHelper.removeDeliveredNotification(notificationID);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void removeAllDeliveredNotifications() {
|
||||
mRNFirebaseLocalMessagingHelper.removeAllDeliveredNotifications();
|
||||
public void setBadge(int badge) {
|
||||
// Store the badge count for later retrieval
|
||||
sharedPreferences.edit().putInt(BADGE_KEY, badge).apply();
|
||||
if (badge == 0) {
|
||||
Log.d(TAG, "Remove badge count");
|
||||
ShortcutBadger.removeCount(this.getReactApplicationContext());
|
||||
} else {
|
||||
Log.d(TAG, "Apply badge count: " + badge);
|
||||
ShortcutBadger.applyCount(this.getReactApplicationContext(), badge);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
|
@ -133,159 +151,163 @@ public class RNFirebaseMessaging extends ReactContextBaseJavaModule implements L
|
|||
FirebaseMessaging.getInstance().unsubscribeFromTopic(topic);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getScheduledLocalNotifications(Promise promise) {
|
||||
ArrayList<Bundle> bundles = mRNFirebaseLocalMessagingHelper.getScheduledLocalNotifications();
|
||||
WritableArray array = Arguments.createArray();
|
||||
for (Bundle bundle : bundles) {
|
||||
array.pushMap(Arguments.fromBundle(bundle));
|
||||
}
|
||||
promise.resolve(array);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setBadgeNumber(int badgeNumber) {
|
||||
mBadgeHelper.setBadgeCount(badgeNumber);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getBadgeNumber(Promise promise) {
|
||||
promise.resolve(mBadgeHelper.getBadgeCount());
|
||||
}
|
||||
|
||||
private void registerTokenRefreshHandler() {
|
||||
IntentFilter intentFilter = new IntentFilter("io.invertase.firebase.messaging.FCMRefreshToken");
|
||||
getReactApplicationContext().registerReceiver(new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (getReactApplicationContext().hasActiveCatalystInstance()) {
|
||||
String token = intent.getStringExtra("token");
|
||||
Utils.sendEvent(getReactApplicationContext(), "messaging_token_refreshed", token);
|
||||
}
|
||||
}
|
||||
}, intentFilter);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void send(ReadableMap remoteMessage) {
|
||||
FirebaseMessaging fm = FirebaseMessaging.getInstance();
|
||||
RemoteMessage.Builder message = new RemoteMessage.Builder(remoteMessage.getString("sender"));
|
||||
|
||||
message.setTtl(remoteMessage.getInt("ttl"));
|
||||
message.setMessageId(remoteMessage.getString("id"));
|
||||
message.setMessageType(remoteMessage.getString("type"));
|
||||
|
||||
if (remoteMessage.hasKey("collapseKey")) {
|
||||
message.setCollapseKey(remoteMessage.getString("collapseKey"));
|
||||
}
|
||||
|
||||
// get data keys and values and add to builder
|
||||
// js side ensures all data values are strings
|
||||
// so no need to check types
|
||||
ReadableMap data = remoteMessage.getMap("data");
|
||||
ReadableMapKeySetIterator iterator = data.keySetIterator();
|
||||
while (iterator.hasNextKey()) {
|
||||
String key = iterator.nextKey();
|
||||
String value = data.getString(key);
|
||||
message.addData(key, value);
|
||||
}
|
||||
|
||||
fm.send(message.build());
|
||||
}
|
||||
|
||||
private void registerMessageHandler() {
|
||||
IntentFilter intentFilter = new IntentFilter("io.invertase.firebase.messaging.ReceiveNotification");
|
||||
|
||||
getReactApplicationContext().registerReceiver(new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (getReactApplicationContext().hasActiveCatalystInstance()) {
|
||||
RemoteMessage message = intent.getParcelableExtra("data");
|
||||
WritableMap params = Arguments.createMap();
|
||||
WritableMap fcmData = Arguments.createMap();
|
||||
|
||||
if (message.getNotification() != null) {
|
||||
Notification notification = message.getNotification();
|
||||
fcmData.putString("title", notification.getTitle());
|
||||
fcmData.putString("body", notification.getBody());
|
||||
fcmData.putString("color", notification.getColor());
|
||||
fcmData.putString("icon", notification.getIcon());
|
||||
fcmData.putString("tag", notification.getTag());
|
||||
fcmData.putString("action", notification.getClickAction());
|
||||
}
|
||||
params.putMap("fcm", fcmData);
|
||||
|
||||
if (message.getData() != null) {
|
||||
Map<String, String> data = message.getData();
|
||||
Set<String> keysIterator = data.keySet();
|
||||
for (String key : keysIterator) {
|
||||
params.putString(key, data.get(key));
|
||||
}
|
||||
}
|
||||
Utils.sendEvent(getReactApplicationContext(), "messaging_notification_received", params);
|
||||
|
||||
}
|
||||
}
|
||||
}, intentFilter);
|
||||
}
|
||||
|
||||
private void registerLocalMessageHandler() {
|
||||
IntentFilter intentFilter = new IntentFilter("io.invertase.firebase.messaging.ReceiveLocalNotification");
|
||||
|
||||
getReactApplicationContext().registerReceiver(new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (getReactApplicationContext().hasActiveCatalystInstance()) {
|
||||
Utils.sendEvent(getReactApplicationContext(), "messaging_notification_received", Arguments.fromBundle(intent.getExtras()));
|
||||
}
|
||||
}
|
||||
}, intentFilter);
|
||||
}
|
||||
|
||||
private WritableMap parseIntent(Intent intent) {
|
||||
WritableMap params;
|
||||
Bundle extras = intent.getExtras();
|
||||
if (extras != null) {
|
||||
try {
|
||||
params = Arguments.fromBundle(extras);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, e.getMessage());
|
||||
params = Arguments.createMap();
|
||||
}
|
||||
} else {
|
||||
params = Arguments.createMap();
|
||||
}
|
||||
WritableMap fcm = Arguments.createMap();
|
||||
fcm.putString("action", intent.getAction());
|
||||
params.putMap("fcm", fcm);
|
||||
|
||||
params.putBoolean("opened_from_tray", true);
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostResume() {
|
||||
mRNFirebaseLocalMessagingHelper.setApplicationForeground(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostPause() {
|
||||
mRNFirebaseLocalMessagingHelper.setApplicationForeground(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostDestroy() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
|
||||
// todo hmm?
|
||||
// FCM functionality does not need this function
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
// todo hmm?
|
||||
Utils.sendEvent(getReactApplicationContext(), "messaging_notification_received", parseIntent(intent));
|
||||
WritableMap messageMap = parseIntentForMessage(intent);
|
||||
if (messageMap != null) {
|
||||
Log.d(TAG, "onNewIntent called with new FCM message");
|
||||
Utils.sendEvent(getReactApplicationContext(), "messaging_message_received", messageMap);
|
||||
}
|
||||
}
|
||||
|
||||
private WritableMap parseIntentForMessage(Intent intent) {
|
||||
// Check if FCM data exists
|
||||
if (intent.getExtras() == null || !intent.hasExtra("google.message_id")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Bundle extras = intent.getExtras();
|
||||
|
||||
WritableMap messageMap = Arguments.createMap();
|
||||
WritableMap dataMap = Arguments.createMap();
|
||||
|
||||
for (String key : extras.keySet()) {
|
||||
if (key.equals("collapse_key")) {
|
||||
messageMap.putString("collapseKey", extras.getString("collapse_key"));
|
||||
} else if (key.equals("from")) {
|
||||
messageMap.putString("from", extras.getString("from"));
|
||||
} else if (key.equals("google.message_id")) {
|
||||
messageMap.putString("messageId", extras.getString("google.message_id"));
|
||||
} else if (key.equals("google.sent_time")) {
|
||||
messageMap.putDouble("sentTime", extras.getLong("google.sent_time"));
|
||||
} else {
|
||||
dataMap.putString(key, extras.getString(key));
|
||||
}
|
||||
}
|
||||
messageMap.putMap("data", dataMap);
|
||||
messageMap.putBoolean("openedFromTray", true);
|
||||
|
||||
return messageMap;
|
||||
}
|
||||
|
||||
private class MessageReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (getReactApplicationContext().hasActiveCatalystInstance()) {
|
||||
Log.d(TAG, "Received new message");
|
||||
|
||||
RemoteMessage message = intent.getParcelableExtra("message");
|
||||
WritableMap messageMap = buildMessageMap(message);
|
||||
|
||||
Utils.sendEvent(getReactApplicationContext(), "messaging_message_received", messageMap);
|
||||
}
|
||||
}
|
||||
|
||||
private WritableMap buildMessageMap(RemoteMessage message) {
|
||||
WritableMap messageMap = Arguments.createMap();
|
||||
WritableMap dataMap = Arguments.createMap();
|
||||
|
||||
if (message.getCollapseKey() != null) {
|
||||
messageMap.putString("collapseKey", message.getCollapseKey());
|
||||
}
|
||||
|
||||
if (message.getData() != null) {
|
||||
for (Map.Entry<String, String> e : message.getData().entrySet()) {
|
||||
dataMap.putString(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
messageMap.putMap("data", dataMap);
|
||||
|
||||
if (message.getFrom() != null) {
|
||||
messageMap.putString("from", message.getFrom());
|
||||
}
|
||||
if (message.getMessageId() != null) {
|
||||
messageMap.putString("messageId", message.getMessageId());
|
||||
}
|
||||
if (message.getMessageType() != null) {
|
||||
messageMap.putString("messageType", message.getMessageType());
|
||||
}
|
||||
|
||||
if (message.getNotification() != null) {
|
||||
Notification notification = message.getNotification();
|
||||
|
||||
WritableMap notificationMap = Arguments.createMap();
|
||||
|
||||
if (notification.getBody() != null) {
|
||||
notificationMap.putString("body", notification.getBody());
|
||||
}
|
||||
if (notification.getBodyLocalizationArgs() != null) {
|
||||
WritableArray bodyArgs = Arguments.createArray();
|
||||
for (String arg : notification.getBodyLocalizationArgs()) {
|
||||
bodyArgs.pushString(arg);
|
||||
}
|
||||
notificationMap.putArray("bodyLocalizationArgs", bodyArgs);
|
||||
}
|
||||
if (notification.getBodyLocalizationKey() != null) {
|
||||
notificationMap.putString("bodyLocalizationKey", notification.getBodyLocalizationKey());
|
||||
}
|
||||
if (notification.getClickAction() != null) {
|
||||
notificationMap.putString("clickAction", notification.getClickAction());
|
||||
}
|
||||
if (notification.getColor() != null) {
|
||||
notificationMap.putString("color", notification.getColor());
|
||||
}
|
||||
if (notification.getIcon() != null) {
|
||||
notificationMap.putString("icon", notification.getIcon());
|
||||
}
|
||||
if (notification.getLink() != null) {
|
||||
notificationMap.putString("link", notification.getLink().toString());
|
||||
}
|
||||
if (notification.getSound() != null) {
|
||||
notificationMap.putString("sound", notification.getSound());
|
||||
}
|
||||
if (notification.getTag() != null) {
|
||||
notificationMap.putString("tag", notification.getTag());
|
||||
}
|
||||
if (notification.getTitle() != null) {
|
||||
notificationMap.putString("title", notification.getTitle());
|
||||
}
|
||||
if (notification.getTitleLocalizationArgs() != null) {
|
||||
WritableArray titleArgs = Arguments.createArray();
|
||||
for (String arg : notification.getTitleLocalizationArgs()) {
|
||||
titleArgs.pushString(arg);
|
||||
}
|
||||
notificationMap.putArray("titleLocalizationArgs", titleArgs);
|
||||
}
|
||||
if (notification.getTitleLocalizationKey() != null) {
|
||||
notificationMap.putString("titleLocalizationKey", notification.getTitleLocalizationKey());
|
||||
}
|
||||
|
||||
messageMap.putMap("notification", notificationMap);
|
||||
}
|
||||
|
||||
messageMap.putBoolean("openedFromTray", false);
|
||||
messageMap.putDouble("sentTime", message.getSentTime());
|
||||
|
||||
if (message.getTo() != null) {
|
||||
messageMap.putString("to", message.getTo());
|
||||
}
|
||||
|
||||
messageMap.putDouble("ttl", message.getTtl());
|
||||
|
||||
return messageMap;
|
||||
}
|
||||
}
|
||||
|
||||
private class RefreshTokenReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (getReactApplicationContext().hasActiveCatalystInstance()) {
|
||||
String token = FirebaseInstanceId.getInstance().getToken();
|
||||
Log.d(TAG, "Received new token: " + token);
|
||||
|
||||
Utils.sendEvent(getReactApplicationContext(), "messaging_token_refreshed", token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package io.invertase.firebase.messaging;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||
import com.google.firebase.messaging.RemoteMessage;
|
||||
|
||||
public class RNFirebaseMessagingService extends FirebaseMessagingService {
|
||||
private static final String TAG = "RNFMessagingService";
|
||||
public static final String MESSAGE_EVENT = "messaging-message";
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(RemoteMessage message) {
|
||||
Log.d(TAG, "onMessageReceived event received");
|
||||
|
||||
// Build an Intent to pass the token to the RN Application
|
||||
Intent messageEvent = new Intent(MESSAGE_EVENT);
|
||||
messageEvent.putExtra("message", message);
|
||||
|
||||
// Broadcast it so it is only available to the RN Application
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(messageEvent);
|
||||
}
|
||||
}
|
|
@ -17,7 +17,9 @@
|
|||
8376F7141F7C149100D45A85 /* RNFirebaseFirestoreDocumentReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F70E1F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.m */; };
|
||||
8376F7151F7C149100D45A85 /* RNFirebaseFirestore.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F7101F7C149000D45A85 /* RNFirebaseFirestore.m */; };
|
||||
8376F7161F7C149100D45A85 /* RNFirebaseFirestoreCollectionReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */; };
|
||||
838E36FE201B9169004DCD3A /* NewRNFirebaseMessaging.m in Sources */ = {isa = PBXBuildFile; fileRef = 838E36FD201B9169004DCD3A /* NewRNFirebaseMessaging.m */; };
|
||||
838E36FE201B9169004DCD3A /* RNFirebaseMessaging.m in Sources */ = {isa = PBXBuildFile; fileRef = 838E36FD201B9169004DCD3A /* RNFirebaseMessaging.m */; };
|
||||
838E372320231DF0004DCD3A /* RNFirebaseInstanceId.m in Sources */ = {isa = PBXBuildFile; fileRef = 838E372220231DF0004DCD3A /* RNFirebaseInstanceId.m */; };
|
||||
838E372720231E15004DCD3A /* RNFirebaseNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 838E372520231E15004DCD3A /* RNFirebaseNotifications.m */; };
|
||||
839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */; };
|
||||
839D916D1EF3E20B0077C7C8 /* RNFirebaseAdMobInterstitial.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91511EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.m */; };
|
||||
839D916E1EF3E20B0077C7C8 /* RNFirebaseAdMobRewardedVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91531EF3E20A0077C7C8 /* RNFirebaseAdMobRewardedVideo.m */; };
|
||||
|
@ -26,7 +28,6 @@
|
|||
839D91711EF3E20B0077C7C8 /* RNFirebaseRemoteConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D915C1EF3E20A0077C7C8 /* RNFirebaseRemoteConfig.m */; };
|
||||
839D91721EF3E20B0077C7C8 /* RNFirebaseCrash.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D915F1EF3E20A0077C7C8 /* RNFirebaseCrash.m */; };
|
||||
839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91621EF3E20A0077C7C8 /* RNFirebaseDatabase.m */; };
|
||||
839D91741EF3E20B0077C7C8 /* RNFirebaseMessaging.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91651EF3E20A0077C7C8 /* RNFirebaseMessaging.m */; };
|
||||
839D91751EF3E20B0077C7C8 /* RNFirebasePerformance.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91681EF3E20A0077C7C8 /* RNFirebasePerformance.m */; };
|
||||
83C3EEEE1FA1EACC00B64D3C /* RNFirebaseUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 83C3EEEC1FA1EACC00B64D3C /* RNFirebaseUtil.m */; };
|
||||
BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = BA84AE561FA9E59800E79390 /* RNFirebaseStorage.m */; };
|
||||
|
@ -67,8 +68,12 @@
|
|||
8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFirestoreCollectionReference.m; sourceTree = "<group>"; };
|
||||
8376F7121F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestoreDocumentReference.h; sourceTree = "<group>"; };
|
||||
8376F7131F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestoreCollectionReference.h; sourceTree = "<group>"; };
|
||||
838E36FC201B9169004DCD3A /* NewRNFirebaseMessaging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewRNFirebaseMessaging.h; sourceTree = "<group>"; };
|
||||
838E36FD201B9169004DCD3A /* NewRNFirebaseMessaging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NewRNFirebaseMessaging.m; sourceTree = "<group>"; };
|
||||
838E36FC201B9169004DCD3A /* RNFirebaseMessaging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseMessaging.h; sourceTree = "<group>"; };
|
||||
838E36FD201B9169004DCD3A /* RNFirebaseMessaging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseMessaging.m; sourceTree = "<group>"; };
|
||||
838E372120231DF0004DCD3A /* RNFirebaseInstanceId.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseInstanceId.h; sourceTree = "<group>"; };
|
||||
838E372220231DF0004DCD3A /* RNFirebaseInstanceId.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseInstanceId.m; sourceTree = "<group>"; };
|
||||
838E372520231E15004DCD3A /* RNFirebaseNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseNotifications.m; sourceTree = "<group>"; };
|
||||
838E372620231E15004DCD3A /* RNFirebaseNotifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseNotifications.h; sourceTree = "<group>"; };
|
||||
839D914E1EF3E20A0077C7C8 /* RNFirebaseAdMob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMob.h; sourceTree = "<group>"; };
|
||||
839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMob.m; sourceTree = "<group>"; };
|
||||
839D91501EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobInterstitial.h; sourceTree = "<group>"; };
|
||||
|
@ -85,8 +90,6 @@
|
|||
839D915F1EF3E20A0077C7C8 /* RNFirebaseCrash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseCrash.m; sourceTree = "<group>"; };
|
||||
839D91611EF3E20A0077C7C8 /* RNFirebaseDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseDatabase.h; sourceTree = "<group>"; };
|
||||
839D91621EF3E20A0077C7C8 /* RNFirebaseDatabase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseDatabase.m; sourceTree = "<group>"; };
|
||||
839D91641EF3E20A0077C7C8 /* RNFirebaseMessaging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseMessaging.h; sourceTree = "<group>"; };
|
||||
839D91651EF3E20A0077C7C8 /* RNFirebaseMessaging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseMessaging.m; sourceTree = "<group>"; };
|
||||
839D91671EF3E20A0077C7C8 /* RNFirebasePerformance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebasePerformance.h; sourceTree = "<group>"; };
|
||||
839D91681EF3E20A0077C7C8 /* RNFirebasePerformance.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebasePerformance.m; sourceTree = "<group>"; };
|
||||
839D91771EF3E22F0077C7C8 /* RNFirebaseEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNFirebaseEvents.h; path = RNFirebase/RNFirebaseEvents.h; sourceTree = "<group>"; };
|
||||
|
@ -130,6 +133,8 @@
|
|||
58B511D21A9E6C8500147676 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
838E372420231E15004DCD3A /* notifications */,
|
||||
838E372020231DF0004DCD3A /* instanceid */,
|
||||
8336930F1FD80DE800AA806B /* fabric */,
|
||||
BA84AE541FA9E59800E79390 /* storage */,
|
||||
17AF4F681F59CDBF00C02336 /* links */,
|
||||
|
@ -182,6 +187,26 @@
|
|||
path = RNFirebase/firestore;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
838E372020231DF0004DCD3A /* instanceid */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
838E372120231DF0004DCD3A /* RNFirebaseInstanceId.h */,
|
||||
838E372220231DF0004DCD3A /* RNFirebaseInstanceId.m */,
|
||||
);
|
||||
name = instanceid;
|
||||
path = RNFirebase/instanceid;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
838E372420231E15004DCD3A /* notifications */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
838E372520231E15004DCD3A /* RNFirebaseNotifications.m */,
|
||||
838E372620231E15004DCD3A /* RNFirebaseNotifications.h */,
|
||||
);
|
||||
name = notifications;
|
||||
path = RNFirebase/notifications;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
839D914D1EF3E20A0077C7C8 /* admob */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -259,10 +284,8 @@
|
|||
839D91631EF3E20A0077C7C8 /* messaging */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
838E36FC201B9169004DCD3A /* NewRNFirebaseMessaging.h */,
|
||||
838E36FD201B9169004DCD3A /* NewRNFirebaseMessaging.m */,
|
||||
839D91641EF3E20A0077C7C8 /* RNFirebaseMessaging.h */,
|
||||
839D91651EF3E20A0077C7C8 /* RNFirebaseMessaging.m */,
|
||||
838E36FC201B9169004DCD3A /* RNFirebaseMessaging.h */,
|
||||
838E36FD201B9169004DCD3A /* RNFirebaseMessaging.m */,
|
||||
);
|
||||
name = messaging;
|
||||
path = RNFirebase/messaging;
|
||||
|
@ -344,11 +367,12 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
838E372320231DF0004DCD3A /* RNFirebaseInstanceId.m in Sources */,
|
||||
839D916E1EF3E20B0077C7C8 /* RNFirebaseAdMobRewardedVideo.m in Sources */,
|
||||
839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */,
|
||||
17AF4F6B1F59CDBF00C02336 /* RNFirebaseLinks.m in Sources */,
|
||||
8376F7161F7C149100D45A85 /* RNFirebaseFirestoreCollectionReference.m in Sources */,
|
||||
838E36FE201B9169004DCD3A /* NewRNFirebaseMessaging.m in Sources */,
|
||||
838E36FE201B9169004DCD3A /* RNFirebaseMessaging.m in Sources */,
|
||||
8376F7151F7C149100D45A85 /* RNFirebaseFirestore.m in Sources */,
|
||||
839D91701EF3E20B0077C7C8 /* RNFirebaseAuth.m in Sources */,
|
||||
8323CF091F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m in Sources */,
|
||||
|
@ -358,11 +382,11 @@
|
|||
833693131FD824EF00AA806B /* RNFirebaseCrashlytics.m in Sources */,
|
||||
D950369E1D19C77400F7094D /* RNFirebase.m in Sources */,
|
||||
839D91731EF3E20B0077C7C8 /* RNFirebaseDatabase.m in Sources */,
|
||||
838E372720231E15004DCD3A /* RNFirebaseNotifications.m in Sources */,
|
||||
BA84AE571FA9E59800E79390 /* RNFirebaseStorage.m in Sources */,
|
||||
8323CF071F6FBD870071420B /* NativeExpressComponent.m in Sources */,
|
||||
83C3EEEE1FA1EACC00B64D3C /* RNFirebaseUtil.m in Sources */,
|
||||
839D91721EF3E20B0077C7C8 /* RNFirebaseCrash.m in Sources */,
|
||||
839D91741EF3E20B0077C7C8 /* RNFirebaseMessaging.m in Sources */,
|
||||
839D91751EF3E20B0077C7C8 /* RNFirebasePerformance.m in Sources */,
|
||||
8323CF061F6FBD870071420B /* BannerComponent.m in Sources */,
|
||||
839D916D1EF3E20B0077C7C8 /* RNFirebaseAdMobInterstitial.m in Sources */,
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef RNFirebaseInstanceId_h
|
||||
#define RNFirebaseInstanceId_h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if __has_include(<FirebaseInstanceID/FirebaseInstanceID.h>)
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
@interface RNFirebaseInstanceId : NSObject <RCTBridgeModule> {
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@interface RNFirebaseInstanceId : NSObject
|
||||
@end
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
#import "RNFirebaseInstanceId.h"
|
||||
|
||||
#if __has_include(<FirebaseInstanceID/FIRInstanceID.h>)
|
||||
#import <FirebaseInstanceID/FIRInstanceID.h>
|
||||
|
||||
@implementation RNFirebaseInstanceId
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
RCT_EXPORT_METHOD(delete:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[FIRInstanceID instanceID] deleteIDWithHandler:^(NSError * _Nullable error) {
|
||||
if (error) {
|
||||
reject(@"instance_id_error", @"Failed to delete instance id", error);
|
||||
} else {
|
||||
resolve(nil);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(get:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[FIRInstanceID instanceID] getIDWithHandler:^(NSString * _Nullable identity, NSError * _Nullable error) {
|
||||
if (error) {
|
||||
reject(@"instance_id_error", @"Failed to get instance id", error);
|
||||
} else {
|
||||
resolve(identity);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@implementation RNFirebaseInstanceId
|
||||
@end
|
||||
#endif
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef NewRNFirebaseMessaging_h
|
||||
#define NewRNFirebaseMessaging_h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if __has_include(<FirebaseMessaging/FirebaseMessaging.h>)
|
||||
#import <FirebaseMessaging/FirebaseMessaging.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
@interface NewRNFirebaseMessaging : RCTEventEmitter<RCTBridgeModule, FIRMessagingDelegate>
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@interface NewRNFirebaseMessaging : NSObject
|
||||
@end
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,132 +0,0 @@
|
|||
#import "NewRNFirebaseMessaging.h"
|
||||
|
||||
#if __has_include(<FirebaseMessaging/FirebaseMessaging.h>)
|
||||
@import UserNotifications;
|
||||
#import "RNFirebaseEvents.h"
|
||||
#import "RNFirebaseUtil.h"
|
||||
#import <FirebaseMessaging/FirebaseMessaging.h>
|
||||
#import <FirebaseInstanceID/FIRInstanceID.h>
|
||||
|
||||
#import <React/RCTEventDispatcher.h>
|
||||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTUtils.h>
|
||||
|
||||
@interface NewRNFirebaseMessaging ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation NewRNFirebaseMessaging
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
NSLog(@"Setting up RNFirebaseMessaging instance");
|
||||
[self initialiseMessaging];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)initialiseMessaging {
|
||||
// Establish Firebase managed data channel
|
||||
[FIRMessaging messaging].shouldEstablishDirectChannel = YES;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
|
||||
}
|
||||
|
||||
// ** Start React Module methods **
|
||||
RCT_EXPORT_METHOD(getToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
resolve([[FIRInstanceID instanceID] token]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(requestPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
if (RCTRunningInAppExtension()) {
|
||||
reject(@"request_permission_unavailable", @"requestPermission is not supported in App Extensions", nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
|
||||
UIUserNotificationType types = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
|
||||
[RCTSharedApplication() registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:types categories:nil]];
|
||||
// Unfortunately on iOS 9 or below, there's no way to tell whether the user accepted or
|
||||
// rejected the permissions popup
|
||||
// TODO: Is there something we can listen for?
|
||||
resolve(@{@"status":@"unknown"});
|
||||
} else {
|
||||
// iOS 10 or later
|
||||
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
// For iOS 10 display notification (sent via APNS)
|
||||
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
|
||||
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
||||
if (granted) {
|
||||
resolve(@{@"status": @"granted"});
|
||||
} else {
|
||||
reject(@"permission_error", @"Failed to grant permission", error);
|
||||
}
|
||||
}];
|
||||
#endif
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[RCTSharedApplication() registerForRemoteNotifications];
|
||||
});
|
||||
}
|
||||
|
||||
// Non Web SDK methods
|
||||
|
||||
RCT_EXPORT_METHOD(deleteInstanceId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[FIRInstanceID instanceID] deleteIDWithHandler:^(NSError * _Nullable error) {
|
||||
if (!error) {
|
||||
resolve(nil);
|
||||
} else {
|
||||
reject(@"instance_id_error", @"Failed to delete instance id", error);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getBadgeNumber: (RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
resolve(@([RCTSharedApplication() applicationIconBadgeNumber]));
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
|
||||
UILocalNotification *localUserInfo = [self bridge].launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
|
||||
if (localUserInfo) {
|
||||
resolve([[localUserInfo userInfo] copy]);
|
||||
} else {
|
||||
resolve([[self bridge].launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] copy]);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(subscribeToTopic: (NSString*) topic) {
|
||||
[[FIRMessaging messaging] subscribeToTopic:topic];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(unsubscribeFromTopic: (NSString*) topic) {
|
||||
[[FIRMessaging messaging] unsubscribeFromTopic:topic];
|
||||
}
|
||||
|
||||
|
||||
RCT_EXPORT_METHOD(setBadgeNumber: (NSInteger*) number) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[RCTSharedApplication() setApplicationIconBadgeNumber:*number];
|
||||
});
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents {
|
||||
return @[MESSAGING_MESSAGE_RECEIVED, MESSAGING_TOKEN_REFRESHED];
|
||||
}
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@implementation NewRNFirebaseMessaging
|
||||
@end
|
||||
#endif
|
|
@ -7,22 +7,10 @@
|
|||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
@import UserNotifications;
|
||||
|
||||
@interface RNFirebaseMessaging : RCTEventEmitter<RCTBridgeModule, FIRMessagingDelegate>
|
||||
|
||||
typedef void (^RCTRemoteNotificationCallback)(UIBackgroundFetchResult result);
|
||||
typedef void (^RCTWillPresentNotificationCallback)(UNNotificationPresentationOptions result);
|
||||
typedef void (^RCTNotificationResponseCallback)();
|
||||
|
||||
@property (nonatomic, assign) bool connectedToFCM;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
+ (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo;
|
||||
+ (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull RCTRemoteNotificationCallback)completionHandler;
|
||||
+ (void)didReceiveLocalNotification:(nonnull UILocalNotification *)notification;
|
||||
+ (void)didReceiveNotificationResponse:(nonnull UNNotificationResponse *)response withCompletionHandler:(nonnull RCTNotificationResponseCallback)completionHandler;
|
||||
+ (void)willPresentNotification:(nonnull UNNotification *)notification withCompletionHandler:(nonnull RCTWillPresentNotificationCallback)completionHandler;
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#import "RNFirebaseMessaging.h"
|
||||
|
||||
@import UserNotifications;
|
||||
#if __has_include(<FirebaseMessaging/FirebaseMessaging.h>)
|
||||
@import UserNotifications;
|
||||
#import "RNFirebaseEvents.h"
|
||||
#import "RNFirebaseUtil.h"
|
||||
#import <FirebaseMessaging/FirebaseMessaging.h>
|
||||
|
@ -11,167 +11,14 @@
|
|||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTUtils.h>
|
||||
|
||||
@implementation RCTConvert (NSCalendarUnit)
|
||||
|
||||
RCT_ENUM_CONVERTER(NSCalendarUnit,
|
||||
(@{
|
||||
@"year": @(NSCalendarUnitYear),
|
||||
@"month": @(NSCalendarUnitMonth),
|
||||
@"week": @(NSCalendarUnitWeekOfYear),
|
||||
@"day": @(NSCalendarUnitDay),
|
||||
@"hour": @(NSCalendarUnitHour),
|
||||
@"minute": @(NSCalendarUnitMinute)
|
||||
}),
|
||||
0,
|
||||
integerValue)
|
||||
@end
|
||||
|
||||
|
||||
@implementation RCTConvert (UNNotificationRequest)
|
||||
|
||||
+ (UNNotificationRequest *)UNNotificationRequest:(id)json
|
||||
{
|
||||
NSDictionary<NSString *, id> *details = [self NSDictionary:json];
|
||||
UNMutableNotificationContent *content = [UNMutableNotificationContent new];
|
||||
content.title =[RCTConvert NSString:details[@"title"]];
|
||||
content.body =[RCTConvert NSString:details[@"body"]];
|
||||
NSString* sound = [RCTConvert NSString:details[@"sound"]];
|
||||
if(sound != nil){
|
||||
content.sound = [UNNotificationSound soundNamed:sound];
|
||||
}else{
|
||||
content.sound = [UNNotificationSound defaultSound];
|
||||
}
|
||||
content.categoryIdentifier = [RCTConvert NSString:details[@"click_action"]];
|
||||
content.userInfo = details;
|
||||
content.badge = [RCTConvert NSNumber:details[@"badge"]];
|
||||
|
||||
if([details objectForKey:@"show_in_foreground"] != nil) {
|
||||
if([(NSNumber *)details[@"show_in_foreground"] boolValue] == YES) {
|
||||
[content setValue:@YES forKeyPath:@"shouldAlwaysAlertWhileAppIsForeground"];
|
||||
}
|
||||
}
|
||||
|
||||
NSDate *fireDate = [RCTConvert NSDate:details[@"fire_date"]];
|
||||
|
||||
if(fireDate == nil){
|
||||
return [UNNotificationRequest requestWithIdentifier:[RCTConvert NSString:details[@"id"]] content:content trigger:nil];
|
||||
}
|
||||
|
||||
NSCalendarUnit interval = [RCTConvert NSCalendarUnit:details[@"repeat_interval"]];
|
||||
NSCalendarUnit unitFlags;
|
||||
switch (interval) {
|
||||
case NSCalendarUnitMinute: {
|
||||
unitFlags = NSCalendarUnitSecond;
|
||||
break;
|
||||
}
|
||||
case NSCalendarUnitHour: {
|
||||
unitFlags = NSCalendarUnitMinute | NSCalendarUnitSecond;
|
||||
break;
|
||||
}
|
||||
case NSCalendarUnitDay: {
|
||||
unitFlags = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
|
||||
break;
|
||||
}
|
||||
case NSCalendarUnitWeekOfYear: {
|
||||
unitFlags = NSCalendarUnitWeekday | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
|
||||
break;
|
||||
}
|
||||
case NSCalendarUnitMonth:{
|
||||
unitFlags = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
|
||||
}
|
||||
case NSCalendarUnitYear:{
|
||||
unitFlags = NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
|
||||
}
|
||||
default:
|
||||
unitFlags = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
|
||||
break;
|
||||
}
|
||||
NSDateComponents *components = [[NSCalendar currentCalendar] components:unitFlags fromDate:fireDate];
|
||||
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:interval != 0];
|
||||
return [UNNotificationRequest requestWithIdentifier:[RCTConvert NSString:details[@"id"]] content:content trigger:trigger];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTConvert (UILocalNotification)
|
||||
|
||||
+ (UILocalNotification *)UILocalNotification:(id)json
|
||||
{
|
||||
NSDictionary<NSString *, id> *details = [self NSDictionary:json];
|
||||
UILocalNotification *notification = [UILocalNotification new];
|
||||
notification.fireDate = [RCTConvert NSDate:details[@"fire_date"]] ?: [NSDate date];
|
||||
if([notification respondsToSelector:@selector(setAlertTitle:)]){
|
||||
[notification setAlertTitle:[RCTConvert NSString:details[@"title"]]];
|
||||
}
|
||||
notification.alertBody = [RCTConvert NSString:details[@"body"]];
|
||||
notification.alertAction = [RCTConvert NSString:details[@"alert_action"]];
|
||||
notification.soundName = [RCTConvert NSString:details[@"sound"]] ?: UILocalNotificationDefaultSoundName;
|
||||
notification.userInfo = details;
|
||||
notification.category = [RCTConvert NSString:details[@"click_action"]];
|
||||
notification.repeatInterval = [RCTConvert NSCalendarUnit:details[@"repeat_interval"]];
|
||||
notification.applicationIconBadgeNumber = [RCTConvert NSInteger:details[@"badge"]];
|
||||
return notification;
|
||||
}
|
||||
|
||||
RCT_ENUM_CONVERTER(UIBackgroundFetchResult, (@{
|
||||
@"UIBackgroundFetchResultNewData": @(UIBackgroundFetchResultNewData),
|
||||
@"UIBackgroundFetchResultNoData": @(UIBackgroundFetchResultNoData),
|
||||
@"UIBackgroundFetchResultFailed": @(UIBackgroundFetchResultFailed),
|
||||
}), UIBackgroundFetchResultNoData, integerValue)
|
||||
|
||||
RCT_ENUM_CONVERTER(UNNotificationPresentationOptions, (@{
|
||||
@"UNNotificationPresentationOptionAll": @(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound),
|
||||
@"UNNotificationPresentationOptionNone": @(UNNotificationPresentationOptionNone)}), UIBackgroundFetchResultNoData, integerValue)
|
||||
|
||||
@end
|
||||
|
||||
@interface RNFirebaseMessaging ()
|
||||
@property (nonatomic, strong) NSMutableDictionary *notificationCallbacks;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RNFirebaseMessaging
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
+ (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo {
|
||||
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: userInfo];
|
||||
[data setValue:@"remote_notification" forKey:@"_notificationType"];
|
||||
[data setValue:@(RCTSharedApplication().applicationState == UIApplicationStateInactive) forKey:@"opened_from_tray"];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MESSAGING_NOTIFICATION_RECEIVED object:self userInfo:@{@"data": data}];
|
||||
}
|
||||
|
||||
+ (void)didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull RCTRemoteNotificationCallback)completionHandler {
|
||||
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: userInfo];
|
||||
[data setValue:@"remote_notification" forKey:@"_notificationType"];
|
||||
[data setValue:@(RCTSharedApplication().applicationState == UIApplicationStateInactive) forKey:@"opened_from_tray"];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MESSAGING_NOTIFICATION_RECEIVED object:self userInfo:@{@"data": data, @"completionHandler": completionHandler}];
|
||||
}
|
||||
|
||||
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification {
|
||||
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: notification.userInfo];
|
||||
[data setValue:@"local_notification" forKey:@"_notificationType"];
|
||||
[data setValue:@(RCTSharedApplication().applicationState == UIApplicationStateInactive) forKey:@"opened_from_tray"];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MESSAGING_NOTIFICATION_RECEIVED object:self userInfo:@{@"data": data}];
|
||||
}
|
||||
|
||||
+ (void)willPresentNotification:(UNNotification *)notification withCompletionHandler:(nonnull RCTWillPresentNotificationCallback)completionHandler
|
||||
{
|
||||
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: notification.request.content.userInfo];
|
||||
[data setValue:@"will_present_notification" forKey:@"_notificationType"];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MESSAGING_NOTIFICATION_RECEIVED object:self userInfo:@{@"data": data, @"completionHandler": completionHandler}];
|
||||
}
|
||||
|
||||
+ (void)didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(nonnull RCTNotificationResponseCallback)completionHandler
|
||||
{
|
||||
NSMutableDictionary* data = [[NSMutableDictionary alloc] initWithDictionary: response.notification.request.content.userInfo];
|
||||
[data setValue:@"notification_response" forKey:@"_notificationType"];
|
||||
[data setValue:@YES forKey:@"opened_from_tray"];
|
||||
if (response.actionIdentifier) {
|
||||
[data setValue:response.actionIdentifier forKey:@"_actionIdentifier"];
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:MESSAGING_NOTIFICATION_RECEIVED object:self userInfo:@{@"data": data, @"completionHandler": completionHandler}];
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
|
@ -184,74 +31,56 @@ RCT_EXPORT_MODULE()
|
|||
- (void)initialiseMessaging {
|
||||
// Establish Firebase managed data channel
|
||||
[FIRMessaging messaging].shouldEstablishDirectChannel = YES;
|
||||
|
||||
// Set up listeners for data messages
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(sendDataMessageFailure:)
|
||||
name:FIRMessagingSendErrorNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(sendDataMessageSuccess:)
|
||||
name:FIRMessagingSendSuccessNotification
|
||||
object:nil];
|
||||
|
||||
// Set up internal listener to send notification over bridge
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(handleNotificationReceived:)
|
||||
name:MESSAGING_NOTIFICATION_RECEIVED
|
||||
object:nil];
|
||||
|
||||
// Set this as a delegate for FIRMessaging
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[FIRMessaging messaging].delegate = self;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
}
|
||||
|
||||
- (void)handleNotificationReceived:(NSNotification *)notification {
|
||||
id completionHandler = notification.userInfo[@"completionHandler"];
|
||||
NSMutableDictionary* data = notification.userInfo[@"data"];
|
||||
if(completionHandler != nil){
|
||||
NSString *completionHandlerId = [[NSUUID UUID] UUIDString];
|
||||
if (!self.notificationCallbacks) {
|
||||
// Lazy initialization
|
||||
self.notificationCallbacks = [NSMutableDictionary dictionary];
|
||||
}
|
||||
self.notificationCallbacks[completionHandlerId] = completionHandler;
|
||||
data[@"_completionHandlerId"] = completionHandlerId;
|
||||
}
|
||||
|
||||
[RNFirebaseUtil sendJSEvent:self name:MESSAGING_NOTIFICATION_RECEIVED body:data];
|
||||
}
|
||||
|
||||
|
||||
- (void)sendDataMessageFailure:(NSNotification *)notification {
|
||||
NSString *messageID = (NSString *)notification.userInfo[@"messageID"];
|
||||
NSLog(@"sendDataMessageFailure: %@", messageID);
|
||||
}
|
||||
|
||||
- (void)sendDataMessageSuccess:(NSNotification *)notification {
|
||||
NSString *messageID = (NSString *)notification.userInfo[@"messageID"];
|
||||
NSLog(@"sendDataMessageSuccess: %@", messageID);
|
||||
}
|
||||
|
||||
// ** Start FIRMessagingDelegate methods **
|
||||
// Handle data messages in the background
|
||||
- (void)applicationReceivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage {
|
||||
[RNFirebaseUtil sendJSEvent:self name:MESSAGING_NOTIFICATION_RECEIVED body:[remoteMessage appData]];
|
||||
}
|
||||
|
||||
// Listen for token refreshes
|
||||
- (void)messaging:(nonnull FIRMessaging *)messaging didRefreshRegistrationToken:(nonnull NSString *)fcmToken {
|
||||
NSLog(@"FCM registration token: %@", fcmToken);
|
||||
[RNFirebaseUtil sendJSEvent:self name:MESSAGING_TOKEN_REFRESHED body:fcmToken];
|
||||
}
|
||||
// ** End FIRMessagingDelegate methods **
|
||||
|
||||
// ** Start React Module methods **
|
||||
RCT_EXPORT_METHOD(getToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
resolve([[FIRInstanceID instanceID] token]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(requestPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
if (RCTRunningInAppExtension()) {
|
||||
reject(@"request_permission_unavailable", @"requestPermission is not supported in App Extensions", nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
|
||||
UIUserNotificationType types = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
|
||||
[RCTSharedApplication() registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:types categories:nil]];
|
||||
// Unfortunately on iOS 9 or below, there's no way to tell whether the user accepted or
|
||||
// rejected the permissions popup
|
||||
// TODO: Is there something we can listen for?
|
||||
resolve(@{@"status":@"unknown"});
|
||||
} else {
|
||||
// iOS 10 or later
|
||||
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
// For iOS 10 display notification (sent via APNS)
|
||||
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
|
||||
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
||||
if (granted) {
|
||||
resolve(@{@"status": @"granted"});
|
||||
} else {
|
||||
reject(@"permission_error", @"Failed to grant permission", error);
|
||||
}
|
||||
}];
|
||||
#endif
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[RCTSharedApplication() registerForRemoteNotifications];
|
||||
});
|
||||
}
|
||||
|
||||
// Non Web SDK methods
|
||||
|
||||
RCT_EXPORT_METHOD(getBadge: (RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
resolve(@([RCTSharedApplication() applicationIconBadgeNumber]));
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
|
||||
UILocalNotification *localUserInfo = [self bridge].launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
|
||||
if (localUserInfo) {
|
||||
|
@ -261,51 +90,9 @@ RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecte
|
|||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
resolve([FIRMessaging messaging].FCMToken);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(deleteInstanceId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
[[FIRInstanceID instanceID] deleteIDWithHandler:^(NSError * _Nullable error) {
|
||||
if (!error) {
|
||||
resolve(nil);
|
||||
} else {
|
||||
reject(@"instance_id_error", @"Failed to delete instance id", error);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(requestPermissions:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
if (RCTRunningInAppExtension()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
|
||||
UIUserNotificationType allNotificationTypes =
|
||||
(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
|
||||
UIUserNotificationSettings *settings =
|
||||
[UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
|
||||
[RCTSharedApplication() registerUserNotificationSettings:settings];
|
||||
// Unfortunately on iOS 9 or below, there's no way to tell whether the user accepted or
|
||||
// rejected the permissions popup
|
||||
resolve(@{@"status":@"unknown"});
|
||||
} else {
|
||||
// iOS 10 or later
|
||||
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
// For iOS 10 display notification (sent via APNS)
|
||||
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
||||
UNAuthorizationOptions authOptions =
|
||||
UNAuthorizationOptionAlert
|
||||
| UNAuthorizationOptionSound
|
||||
| UNAuthorizationOptionBadge;
|
||||
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
|
||||
resolve(@{@"granted":@(granted)});
|
||||
}];
|
||||
#endif
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setBadge: (NSInteger*) number) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[RCTSharedApplication() registerForRemoteNotifications];
|
||||
[RCTSharedApplication() setApplicationIconBadgeNumber:*number];
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -317,144 +104,8 @@ RCT_EXPORT_METHOD(unsubscribeFromTopic: (NSString*) topic) {
|
|||
[[FIRMessaging messaging] unsubscribeFromTopic:topic];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(createLocalNotification:(id)data resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
if([UNUserNotificationCenter currentNotificationCenter] != nil){
|
||||
UNNotificationRequest* request = [RCTConvert UNNotificationRequest:data];
|
||||
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
|
||||
if (!error) {
|
||||
resolve(nil);
|
||||
}else{
|
||||
reject(@"notification_error", @"Failed to present local notificaton", error);
|
||||
}
|
||||
}];
|
||||
}else{
|
||||
UILocalNotification* notif = [RCTConvert UILocalNotification:data];
|
||||
[RCTSharedApplication() presentLocalNotificationNow:notif];
|
||||
resolve(nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(scheduleLocalNotification:(id)data resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
if([UNUserNotificationCenter currentNotificationCenter] != nil){
|
||||
UNNotificationRequest* request = [RCTConvert UNNotificationRequest:data];
|
||||
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
|
||||
if (!error) {
|
||||
resolve(nil);
|
||||
}else{
|
||||
reject(@"notification_error", @"Failed to present local notificaton", error);
|
||||
}
|
||||
}];
|
||||
}else{
|
||||
UILocalNotification* notif = [RCTConvert UILocalNotification:data];
|
||||
[RCTSharedApplication() scheduleLocalNotification:notif];
|
||||
resolve(nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(removeDeliveredNotification:(NSString*) notificationId) {
|
||||
if([UNUserNotificationCenter currentNotificationCenter] != nil){
|
||||
[[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[notificationId]];
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(removeAllDeliveredNotifications) {
|
||||
if([UNUserNotificationCenter currentNotificationCenter] != nil){
|
||||
[[UNUserNotificationCenter currentNotificationCenter] removeAllDeliveredNotifications];
|
||||
} else {
|
||||
[RCTSharedApplication() setApplicationIconBadgeNumber: 0];
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(cancelAllLocalNotifications) {
|
||||
if([UNUserNotificationCenter currentNotificationCenter] != nil){
|
||||
[[UNUserNotificationCenter currentNotificationCenter] removeAllPendingNotificationRequests];
|
||||
} else {
|
||||
[RCTSharedApplication() cancelAllLocalNotifications];
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(cancelLocalNotification:(NSString*) notificationId) {
|
||||
if([UNUserNotificationCenter currentNotificationCenter] != nil){
|
||||
[[UNUserNotificationCenter currentNotificationCenter] removePendingNotificationRequestsWithIdentifiers:@[notificationId]];
|
||||
} else {
|
||||
for (UILocalNotification *notification in RCTSharedApplication().scheduledLocalNotifications) {
|
||||
NSDictionary<NSString *, id> *notificationInfo = notification.userInfo;
|
||||
if([notificationId isEqualToString:[notificationInfo valueForKey:@"id"]]){
|
||||
[RCTSharedApplication() cancelLocalNotification:notification];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getScheduledLocalNotifications:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
if([UNUserNotificationCenter currentNotificationCenter] != nil){
|
||||
[[UNUserNotificationCenter currentNotificationCenter] getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
|
||||
NSMutableArray* list = [[NSMutableArray alloc] init];
|
||||
for(UNNotificationRequest * notif in requests){
|
||||
UNMutableNotificationContent *content = notif.content;
|
||||
[list addObject:content.userInfo];
|
||||
}
|
||||
resolve(list);
|
||||
}];
|
||||
} else {
|
||||
NSMutableArray* list = [[NSMutableArray alloc] init];
|
||||
for(UILocalNotification * notif in [RCTSharedApplication() scheduledLocalNotifications]){
|
||||
[list addObject:notif.userInfo];
|
||||
}
|
||||
resolve(list);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setBadgeNumber: (NSInteger*) number) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[RCTSharedApplication() setApplicationIconBadgeNumber:number];
|
||||
});
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getBadgeNumber: (RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
resolve(@([RCTSharedApplication() applicationIconBadgeNumber]));
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(send:(NSDictionary *)remoteMessage) {
|
||||
int64_t ttl = @([[remoteMessage valueForKey:@"ttl"] intValue]).doubleValue;
|
||||
NSString * mId = [remoteMessage valueForKey:@"id"];
|
||||
NSString * receiver = [remoteMessage valueForKey:@"sender"];
|
||||
NSDictionary * data = [remoteMessage valueForKey:@"data"];
|
||||
[[FIRMessaging messaging] sendMessage:data to:receiver withMessageID:mId timeToLive:ttl];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(finishRemoteNotification: (NSString *)completionHandlerId fetchResult:(UIBackgroundFetchResult)result) {
|
||||
RCTRemoteNotificationCallback completionHandler = self.notificationCallbacks[completionHandlerId];
|
||||
if (!completionHandler) {
|
||||
RCTLogError(@"There is no completion handler with completionHandlerId: %@", completionHandlerId);
|
||||
return;
|
||||
}
|
||||
completionHandler(result);
|
||||
[self.notificationCallbacks removeObjectForKey:completionHandlerId];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(finishWillPresentNotification: (NSString *)completionHandlerId fetchResult:(UNNotificationPresentationOptions)result) {
|
||||
RCTWillPresentNotificationCallback completionHandler = self.notificationCallbacks[completionHandlerId];
|
||||
if (!completionHandler) {
|
||||
RCTLogError(@"There is no completion handler with completionHandlerId: %@", completionHandlerId);
|
||||
return;
|
||||
}
|
||||
completionHandler(result);
|
||||
[self.notificationCallbacks removeObjectForKey:completionHandlerId];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(finishNotificationResponse: (NSString *)completionHandlerId) {
|
||||
RCTNotificationResponseCallback completionHandler = self.notificationCallbacks[completionHandlerId];
|
||||
if (!completionHandler) {
|
||||
RCTLogError(@"There is no completion handler with completionHandlerId: %@", completionHandlerId);
|
||||
return;
|
||||
}
|
||||
completionHandler();
|
||||
[self.notificationCallbacks removeObjectForKey:completionHandlerId];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents {
|
||||
return @[MESSAGING_TOKEN_REFRESHED, MESSAGING_NOTIFICATION_RECEIVED];
|
||||
return @[MESSAGING_MESSAGE_RECEIVED, MESSAGING_TOKEN_REFRESHED];
|
||||
}
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef RNFirebaseNotifications_h
|
||||
#define RNFirebaseNotifications_h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if __has_include(<FirebaseMessaging/FirebaseMessaging.h>)
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
@interface RNFirebaseNotifications : RCTEventEmitter<RCTBridgeModule>
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@interface RNFirebaseNotifications : NSObject
|
||||
@end
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,14 @@
|
|||
#import "RNFirebaseNotifications.h"
|
||||
|
||||
#if __has_include(<FirebaseMessaging/FIRMessaging.h>)
|
||||
|
||||
@implementation RNFirebaseNotifications
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@implementation RNFirebaseNotifications
|
||||
@end
|
||||
#endif
|
||||
|
|
@ -18,11 +18,12 @@ import Crashlytics, {
|
|||
} from '../fabric/crashlytics';
|
||||
import Database, { NAMESPACE as DatabaseNamespace } from '../database';
|
||||
import Firestore, { NAMESPACE as FirestoreNamespace } from '../firestore';
|
||||
import InstanceId, { NAMESPACE as InstanceIdNamespace } from '../instanceid';
|
||||
import Links, { NAMESPACE as LinksNamespace } from '../links';
|
||||
import Messaging, { NAMESPACE as MessagingNamespace } from '../messaging';
|
||||
import NewMessaging, {
|
||||
NAMESPACE as NewMessagingNamespace,
|
||||
} from '../messaging/messagingIndex';
|
||||
import Notifications, {
|
||||
NAMESPACE as NotificationsNamespace,
|
||||
} from '../notifications';
|
||||
import Performance, { NAMESPACE as PerfNamespace } from '../perf';
|
||||
import Storage, { NAMESPACE as StorageNamespace } from '../storage';
|
||||
import Utils, { NAMESPACE as UtilsNamespace } from '../utils';
|
||||
|
@ -47,9 +48,10 @@ export default class App {
|
|||
crashlytics: () => Crashlytics,
|
||||
};
|
||||
firestore: () => Firestore;
|
||||
instanceid: () => InstanceId;
|
||||
links: () => Links;
|
||||
messaging: () => Messaging;
|
||||
newmessaging: () => NewMessaging;
|
||||
notifications: () => Notifications;
|
||||
perf: () => Performance;
|
||||
storage: () => Storage;
|
||||
utils: () => Utils;
|
||||
|
@ -87,12 +89,13 @@ export default class App {
|
|||
crashlytics: APPS.appModule(this, CrashlyticsNamespace, Crashlytics),
|
||||
};
|
||||
this.firestore = APPS.appModule(this, FirestoreNamespace, Firestore);
|
||||
this.instanceid = APPS.appModule(this, InstanceIdNamespace, InstanceId);
|
||||
this.links = APPS.appModule(this, LinksNamespace, Links);
|
||||
this.messaging = APPS.appModule(this, MessagingNamespace, Messaging);
|
||||
this.newmessaging = APPS.appModule(
|
||||
this.notifications = APPS.appModule(
|
||||
this,
|
||||
NewMessagingNamespace,
|
||||
NewMessaging
|
||||
NotificationsNamespace,
|
||||
Notifications
|
||||
);
|
||||
this.perf = APPS.appModule(this, PerfNamespace, Performance);
|
||||
this.storage = APPS.appModule(this, StorageNamespace, Storage);
|
||||
|
|
|
@ -39,6 +39,10 @@ import {
|
|||
statics as FirestoreStatics,
|
||||
MODULE_NAME as FirestoreModuleName,
|
||||
} from '../firestore';
|
||||
import {
|
||||
statics as InstanceIdStatics,
|
||||
MODULE_NAME as InstanceIdModuleName,
|
||||
} from '../instanceid';
|
||||
import {
|
||||
statics as LinksStatics,
|
||||
MODULE_NAME as LinksModuleName,
|
||||
|
@ -48,9 +52,9 @@ import {
|
|||
MODULE_NAME as MessagingModuleName,
|
||||
} from '../messaging';
|
||||
import {
|
||||
statics as NewMessagingStatics,
|
||||
MODULE_NAME as NewMessagingModuleName,
|
||||
} from '../messaging/messagingIndex';
|
||||
statics as NotificationsStatics,
|
||||
MODULE_NAME as NotificationsModuleName,
|
||||
} from '../notifications';
|
||||
import {
|
||||
statics as PerformanceStatics,
|
||||
MODULE_NAME as PerfModuleName,
|
||||
|
@ -74,9 +78,10 @@ import type {
|
|||
FabricModule,
|
||||
FirebaseOptions,
|
||||
FirestoreModule,
|
||||
InstanceIdModule,
|
||||
LinksModule,
|
||||
MessagingModule,
|
||||
NewMessagingModule,
|
||||
NotificationsModule,
|
||||
PerformanceModule,
|
||||
StorageModule,
|
||||
UtilsModule,
|
||||
|
@ -93,9 +98,10 @@ class Firebase {
|
|||
database: DatabaseModule;
|
||||
fabric: FabricModule;
|
||||
firestore: FirestoreModule;
|
||||
instanceid: InstanceIdModule;
|
||||
links: LinksModule;
|
||||
messaging: MessagingModule;
|
||||
newmessaging: NewMessagingModule;
|
||||
notifications: NotificationsModule;
|
||||
perf: PerformanceModule;
|
||||
storage: StorageModule;
|
||||
utils: UtilsModule;
|
||||
|
@ -137,16 +143,21 @@ class Firebase {
|
|||
FirestoreStatics,
|
||||
FirestoreModuleName
|
||||
);
|
||||
this.instanceid = APPS.moduleAndStatics(
|
||||
'instanceid',
|
||||
InstanceIdStatics,
|
||||
InstanceIdModuleName
|
||||
);
|
||||
this.links = APPS.moduleAndStatics('links', LinksStatics, LinksModuleName);
|
||||
this.messaging = APPS.moduleAndStatics(
|
||||
'messaging',
|
||||
MessagingStatics,
|
||||
MessagingModuleName
|
||||
);
|
||||
this.newmessaging = APPS.moduleAndStatics(
|
||||
'newmessaging',
|
||||
NewMessagingStatics,
|
||||
NewMessagingModuleName
|
||||
this.notifications = APPS.moduleAndStatics(
|
||||
'notifications',
|
||||
NotificationsStatics,
|
||||
NotificationsModuleName
|
||||
);
|
||||
this.perf = APPS.moduleAndStatics(
|
||||
'perf',
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* @flow
|
||||
* Instance ID representation wrapper
|
||||
*/
|
||||
import ModuleBase from '../../utils/ModuleBase';
|
||||
import { getNativeModule } from '../../utils/native';
|
||||
|
||||
import type App from '../core/firebase-app';
|
||||
|
||||
export const MODULE_NAME = 'RNFirebaseInstanceId';
|
||||
export const NAMESPACE = 'instanceid';
|
||||
|
||||
export default class InstanceId extends ModuleBase {
|
||||
constructor(app: App) {
|
||||
super(app, {
|
||||
moduleName: MODULE_NAME,
|
||||
multiApp: false,
|
||||
namespace: NAMESPACE,
|
||||
});
|
||||
}
|
||||
|
||||
delete(): Promise<void> {
|
||||
return getNativeModule(this).delete();
|
||||
}
|
||||
|
||||
get(): Promise<string> {
|
||||
return getNativeModule(this).get();
|
||||
}
|
||||
}
|
||||
|
||||
export const statics = {};
|
|
@ -1,94 +1,69 @@
|
|||
/**
|
||||
* @flow
|
||||
* Messaging representation wrapper
|
||||
* Messaging (FCM) representation wrapper
|
||||
*/
|
||||
import { Platform, NativeModules } from 'react-native';
|
||||
import { SharedEventEmitter } from '../../utils/events';
|
||||
import INTERNALS from '../../utils/internals';
|
||||
import { getLogger } from '../../utils/log';
|
||||
import ModuleBase from '../../utils/ModuleBase';
|
||||
import RemoteMessage from './RemoteMessage';
|
||||
import { getNativeModule } from '../../utils/native';
|
||||
import { isFunction, isObject } from '../../utils';
|
||||
|
||||
import type App from '../core/firebase-app';
|
||||
|
||||
const EVENT_TYPE = {
|
||||
RefreshToken: 'messaging_token_refreshed',
|
||||
Notification: 'messaging_notification_received',
|
||||
type Notification = {
|
||||
body: string,
|
||||
bodyLocalizationArgs: string[],
|
||||
bodyLocalizationKey: string,
|
||||
clickAction: string,
|
||||
color: string,
|
||||
icon: string,
|
||||
link: string,
|
||||
sound: string,
|
||||
tag: string,
|
||||
title: string,
|
||||
titleLocalizationArgs: string[],
|
||||
titleLocalizationKey: string,
|
||||
};
|
||||
|
||||
const NOTIFICATION_TYPE = {
|
||||
Remote: 'remote_notification',
|
||||
NotificationResponse: 'notification_response',
|
||||
WillPresent: 'will_present_notification',
|
||||
Local: 'local_notification',
|
||||
type Message = {
|
||||
collapseKey: string,
|
||||
data: { [string]: string },
|
||||
from: string,
|
||||
messageId: string,
|
||||
messageType?: string,
|
||||
openedFromTray: boolean,
|
||||
notification?: Notification,
|
||||
sentTime: number,
|
||||
to?: string,
|
||||
ttl?: number,
|
||||
};
|
||||
|
||||
const REMOTE_NOTIFICATION_RESULT = {
|
||||
NewData: 'UIBackgroundFetchResultNewData',
|
||||
NoData: 'UIBackgroundFetchResultNoData',
|
||||
ResultFailed: 'UIBackgroundFetchResultFailed',
|
||||
type OnMessage = Message => any;
|
||||
|
||||
type OnMessageObserver = {
|
||||
next: OnMessage,
|
||||
};
|
||||
|
||||
const WILL_PRESENT_RESULT = {
|
||||
All: 'UNNotificationPresentationOptionAll',
|
||||
None: 'UNNotificationPresentationOptionNone',
|
||||
type OnTokenRefresh = String => any;
|
||||
|
||||
type OnTokenRefreshObserver = {
|
||||
next: OnTokenRefresh,
|
||||
};
|
||||
|
||||
const NATIVE_EVENTS = [EVENT_TYPE.RefreshToken, EVENT_TYPE.Notification];
|
||||
type RemoteMessage = {
|
||||
collapseKey?: string,
|
||||
data: { [string]: string },
|
||||
messageId?: string,
|
||||
messageType?: string,
|
||||
to: string,
|
||||
ttl: number,
|
||||
};
|
||||
|
||||
const FirebaseMessaging = NativeModules.RNFirebaseMessaging;
|
||||
|
||||
/**
|
||||
* IOS only finish function
|
||||
* @param data
|
||||
*/
|
||||
function finish(data) {
|
||||
if (Platform.OS !== 'ios') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._finishCalled && this._completionHandlerId) {
|
||||
let result = data;
|
||||
|
||||
this._finishCalled = true;
|
||||
|
||||
switch (this._notificationType) {
|
||||
case NOTIFICATION_TYPE.Remote:
|
||||
result = result || REMOTE_NOTIFICATION_RESULT.NoData;
|
||||
if (!Object.values(REMOTE_NOTIFICATION_RESULT).includes(result)) {
|
||||
throw new Error(
|
||||
'Invalid REMOTE_NOTIFICATION_RESULT value, use messaging().REMOTE_NOTIFICATION_RESULT'
|
||||
);
|
||||
}
|
||||
|
||||
FirebaseMessaging.finishRemoteNotification(
|
||||
this._completionHandlerId,
|
||||
result
|
||||
);
|
||||
return;
|
||||
case NOTIFICATION_TYPE.NotificationResponse:
|
||||
FirebaseMessaging.finishNotificationResponse(this._completionHandlerId);
|
||||
return;
|
||||
case NOTIFICATION_TYPE.WillPresent:
|
||||
result =
|
||||
result ||
|
||||
(this.show_in_foreground
|
||||
? WILL_PRESENT_RESULT.All
|
||||
: WILL_PRESENT_RESULT.None);
|
||||
if (!Object.values(WILL_PRESENT_RESULT).includes(result)) {
|
||||
throw new Error(
|
||||
'Invalid WILL_PRESENT_RESULT value, use messaging().WILL_PRESENT_RESULT'
|
||||
);
|
||||
}
|
||||
|
||||
FirebaseMessaging.finishWillPresentNotification(
|
||||
this._completionHandlerId,
|
||||
result
|
||||
);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
const NATIVE_EVENTS = [
|
||||
'messaging_message_received',
|
||||
'messaging_token_refreshed',
|
||||
];
|
||||
|
||||
export const MODULE_NAME = 'RNFirebaseMessaging';
|
||||
export const NAMESPACE = 'messaging';
|
||||
|
@ -104,204 +79,139 @@ export default class Messaging extends ModuleBase {
|
|||
multiApp: false,
|
||||
namespace: NAMESPACE,
|
||||
});
|
||||
|
||||
SharedEventEmitter.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onMessage
|
||||
'messaging_message_received',
|
||||
(message: Message) => {
|
||||
SharedEventEmitter.emit('onMessage', message);
|
||||
}
|
||||
);
|
||||
|
||||
SharedEventEmitter.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onMessage
|
||||
'messaging_token_refreshed',
|
||||
(token: string) => {
|
||||
SharedEventEmitter.emit('onTokenRefresh', token);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get EVENT_TYPE(): Object {
|
||||
return EVENT_TYPE;
|
||||
}
|
||||
|
||||
get NOTIFICATION_TYPE(): Object {
|
||||
return NOTIFICATION_TYPE;
|
||||
}
|
||||
|
||||
get REMOTE_NOTIFICATION_RESULT(): Object {
|
||||
return REMOTE_NOTIFICATION_RESULT;
|
||||
}
|
||||
|
||||
get WILL_PRESENT_RESULT(): Object {
|
||||
return WILL_PRESENT_RESULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the notification that triggered application open
|
||||
* @returns {*}
|
||||
*/
|
||||
getInitialNotification(): Promise<Object> {
|
||||
return getNativeModule(this).getInitialNotification();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fcm token for the current device
|
||||
* @returns {*|Promise.<String>}
|
||||
*/
|
||||
getToken(): Promise<string> {
|
||||
return getNativeModule(this).getToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset Instance ID and revokes all tokens.
|
||||
* @returns {*|Promise.<*>}
|
||||
*/
|
||||
deleteInstanceId(): Promise<void> {
|
||||
return getNativeModule(this).deleteInstanceId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and display a local notification
|
||||
* @param notification
|
||||
* @returns {*}
|
||||
*/
|
||||
createLocalNotification(notification: Object): Promise<void> {
|
||||
const _notification = Object.assign({}, notification);
|
||||
_notification.id = _notification.id || new Date().getTime().toString();
|
||||
_notification.local_notification = true;
|
||||
return getNativeModule(this).createLocalNotification(_notification);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param notification
|
||||
* @returns {*}
|
||||
*/
|
||||
scheduleLocalNotification(notification: Object): Promise<void> {
|
||||
const _notification = Object.assign({}, notification);
|
||||
if (!notification.id)
|
||||
return Promise.reject(
|
||||
new Error('An id is required to schedule a local notification.')
|
||||
onMessage(nextOrObserver: OnMessage | OnMessageObserver): () => any {
|
||||
let listener;
|
||||
if (isFunction(nextOrObserver)) {
|
||||
listener = nextOrObserver;
|
||||
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
|
||||
listener = nextOrObserver.next;
|
||||
} else {
|
||||
throw new Error(
|
||||
'Messaging.onMessage failed: First argument must be a function or observer object with a `next` function.'
|
||||
);
|
||||
_notification.local_notification = true;
|
||||
return getNativeModule(this).scheduleLocalNotification(_notification);
|
||||
}
|
||||
|
||||
// TODO: iOS finish
|
||||
getLogger(this).info('Creating onMessage listener');
|
||||
SharedEventEmitter.addListener('onMessage', listener);
|
||||
|
||||
return () => {
|
||||
getLogger(this).info('Removing onMessage listener');
|
||||
SharedEventEmitter.removeListener('onMessage', listener);
|
||||
};
|
||||
}
|
||||
|
||||
onTokenRefresh(
|
||||
nextOrObserver: OnTokenRefresh | OnTokenRefreshObserver
|
||||
): () => any {
|
||||
let listener;
|
||||
if (isFunction(nextOrObserver)) {
|
||||
listener = nextOrObserver;
|
||||
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
|
||||
listener = nextOrObserver.next;
|
||||
} else {
|
||||
throw new Error(
|
||||
'Messaging.OnTokenRefresh failed: First argument must be a function or observer object with a `next` function.'
|
||||
);
|
||||
}
|
||||
|
||||
getLogger(this).info('Creating onTokenRefresh listener');
|
||||
SharedEventEmitter.addListener('onTokenRefresh', listener);
|
||||
|
||||
return () => {
|
||||
getLogger(this).info('Removing onTokenRefresh listener');
|
||||
SharedEventEmitter.removeListener('onTokenRefresh', listener);
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Permission structure?
|
||||
requestPermission(): Promise<void> {
|
||||
return getNativeModule(this).requestPermission();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all scheduled notifications
|
||||
* @returns {Promise.<Array>}
|
||||
* NON WEB-SDK METHODS
|
||||
*/
|
||||
getScheduledLocalNotifications(): Promise<Object[]> {
|
||||
return getNativeModule(this).getScheduledLocalNotifications();
|
||||
getBadge(): Promise<number> {
|
||||
return getNativeModule(this).getBadge();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel a local notification by id - using '*' will cancel
|
||||
* all local notifications.
|
||||
* @param id
|
||||
* @returns {*}
|
||||
*/
|
||||
cancelLocalNotification(id: string): Promise<void> {
|
||||
if (!id) return Promise.reject(new Error('Missing notification id'));
|
||||
if (id === '*') return getNativeModule(this).cancelAllLocalNotifications();
|
||||
return getNativeModule(this).cancelLocalNotification(id);
|
||||
getInitialMessage(): Promise<?Message> {
|
||||
return getNativeModule(this).getInitialMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a delivered notification - using '*' will remove
|
||||
* all delivered notifications.
|
||||
* @param id
|
||||
* @returns {*}
|
||||
*/
|
||||
removeDeliveredNotification(id: string): Promise<void> {
|
||||
if (!id) return Promise.reject(new Error('Missing notification id'));
|
||||
if (id === '*')
|
||||
return getNativeModule(this).removeAllDeliveredNotifications();
|
||||
return getNativeModule(this).removeDeliveredNotification(id);
|
||||
sendMessage(remoteMessage: RemoteMessage): Promise<void> {
|
||||
return getNativeModule(this).send(remoteMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request notification permission
|
||||
* @platforms ios
|
||||
* @returns {*|Promise.<*>}
|
||||
*/
|
||||
requestPermissions(): Promise<void> {
|
||||
return getNativeModule(this).requestPermissions();
|
||||
setBadge(badge: number): void {
|
||||
getNativeModule(this).setBadge(badge);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set notification count badge number
|
||||
* @param n
|
||||
*/
|
||||
setBadgeNumber(n: number): void {
|
||||
getNativeModule(this).setBadgeNumber(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* set notification count badge number
|
||||
* @returns {Promise.<Number>}
|
||||
*/
|
||||
getBadgeNumber(): Promise<number> {
|
||||
return getNativeModule(this).getBadgeNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to messages / notifications
|
||||
* @param listener
|
||||
* @returns {*}
|
||||
*/
|
||||
onMessage(listener: Object => any): () => any {
|
||||
const rnListener = SharedEventEmitter.addListener(
|
||||
EVENT_TYPE.Notification,
|
||||
async event => {
|
||||
const data = {
|
||||
...event,
|
||||
finish,
|
||||
};
|
||||
await listener(data);
|
||||
|
||||
if (!data._finishCalled) {
|
||||
data.finish();
|
||||
}
|
||||
}
|
||||
);
|
||||
return () => rnListener.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to token refresh events
|
||||
* @param listener
|
||||
* @returns {*}
|
||||
*/
|
||||
onTokenRefresh(listener: string => any): () => any {
|
||||
const rnListener = SharedEventEmitter.addListener(
|
||||
EVENT_TYPE.RefreshToken,
|
||||
listener
|
||||
);
|
||||
return () => rnListener.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to a topic
|
||||
* @param topic
|
||||
*/
|
||||
subscribeToTopic(topic: string): void {
|
||||
getNativeModule(this).subscribeToTopic(topic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from a topic
|
||||
* @param topic
|
||||
*/
|
||||
unsubscribeFromTopic(topic: string): void {
|
||||
getNativeModule(this).unsubscribeFromTopic(topic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an upstream message
|
||||
* @param remoteMessage
|
||||
* KNOWN UNSUPPORTED METHODS
|
||||
*/
|
||||
send(remoteMessage: RemoteMessage): Promise<void> {
|
||||
if (!(remoteMessage instanceof RemoteMessage)) {
|
||||
throw new Error(
|
||||
'messaging().send requires an instance of RemoteMessage as the first argument.'
|
||||
);
|
||||
}
|
||||
|
||||
return getNativeModule(this).send(remoteMessage.toJSON());
|
||||
deleteToken() {
|
||||
throw new Error(
|
||||
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
|
||||
'messaging',
|
||||
'deleteToken'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
setBackgroundMessageHandler() {
|
||||
throw new Error(
|
||||
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
|
||||
'messaging',
|
||||
'setBackgroundMessageHandler'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
useServiceWorker() {
|
||||
throw new Error(
|
||||
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
|
||||
'messaging',
|
||||
'useServiceWorker'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const statics = {
|
||||
EVENT_TYPE,
|
||||
NOTIFICATION_TYPE,
|
||||
REMOTE_NOTIFICATION_RESULT,
|
||||
WILL_PRESENT_RESULT,
|
||||
RemoteMessage,
|
||||
// RemoteMessage,
|
||||
};
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
/**
|
||||
* @flow
|
||||
* Messaging (FCM) representation wrapper
|
||||
*/
|
||||
import { SharedEventEmitter } from '../../utils/events';
|
||||
import INTERNALS from '../../utils/internals';
|
||||
import { getLogger } from '../../utils/log';
|
||||
import ModuleBase from '../../utils/ModuleBase';
|
||||
import { getNativeModule } from '../../utils/native';
|
||||
import { isFunction, isObject } from '../../utils';
|
||||
|
||||
import type App from '../core/firebase-app';
|
||||
|
||||
type Message = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
type OnMessage = Message => any;
|
||||
|
||||
type OnMessageObserver = {
|
||||
next: OnMessage,
|
||||
};
|
||||
|
||||
type OnTokenRefresh = String => any;
|
||||
|
||||
type OnTokenRefreshObserver = {
|
||||
next: OnTokenRefresh,
|
||||
};
|
||||
|
||||
type RemoteMessage = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
const NATIVE_EVENTS = [
|
||||
'messaging_message_received',
|
||||
'messaging_token_refreshed',
|
||||
];
|
||||
|
||||
export const MODULE_NAME = 'NewRNFirebaseMessaging';
|
||||
export const NAMESPACE = 'newmessaging';
|
||||
|
||||
/**
|
||||
* @class Messaging
|
||||
*/
|
||||
export default class Messaging extends ModuleBase {
|
||||
constructor(app: App) {
|
||||
super(app, {
|
||||
events: NATIVE_EVENTS,
|
||||
moduleName: MODULE_NAME,
|
||||
multiApp: false,
|
||||
namespace: NAMESPACE,
|
||||
});
|
||||
|
||||
SharedEventEmitter.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onMessage
|
||||
'messaging_message_received',
|
||||
(message: Message) => {
|
||||
SharedEventEmitter.emit('onMessage', message);
|
||||
}
|
||||
);
|
||||
|
||||
SharedEventEmitter.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onMessage
|
||||
'messaging_token_refreshed',
|
||||
(token: string) => {
|
||||
SharedEventEmitter.emit('onTokenRefresh', token);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
deleteToken(token: string): Promise<void> {
|
||||
return getNativeModule(this).deleteToken(token);
|
||||
}
|
||||
|
||||
getToken(): Promise<string> {
|
||||
return getNativeModule(this).getToken();
|
||||
}
|
||||
|
||||
onMessage(nextOrObserver: OnMessage | OnMessageObserver): () => any {
|
||||
let listener;
|
||||
if (isFunction(nextOrObserver)) {
|
||||
listener = nextOrObserver;
|
||||
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
|
||||
listener = nextOrObserver.next;
|
||||
} else {
|
||||
throw new Error(
|
||||
'Messaging.onMessage failed: First argument must be a function or observer object with a `next` function.'
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: iOS finish
|
||||
getLogger(this).info('Creating onMessage listener');
|
||||
SharedEventEmitter.addListener('onMessage', listener);
|
||||
|
||||
return () => {
|
||||
getLogger(this).info('Removing onMessage listener');
|
||||
SharedEventEmitter.removeListener('onMessage', listener);
|
||||
};
|
||||
}
|
||||
|
||||
onTokenRefresh(
|
||||
nextOrObserver: OnTokenRefresh | OnTokenRefreshObserver
|
||||
): () => any {
|
||||
let listener;
|
||||
if (isFunction(nextOrObserver)) {
|
||||
listener = nextOrObserver;
|
||||
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
|
||||
listener = nextOrObserver.next;
|
||||
} else {
|
||||
throw new Error(
|
||||
'Messaging.OnTokenRefresh failed: First argument must be a function or observer object with a `next` function.'
|
||||
);
|
||||
}
|
||||
|
||||
getLogger(this).info('Creating onTokenRefresh listener');
|
||||
SharedEventEmitter.addListener('onTokenRefresh', listener);
|
||||
|
||||
return () => {
|
||||
getLogger(this).info('Removing onTokenRefresh listener');
|
||||
SharedEventEmitter.removeListener('onTokenRefresh', listener);
|
||||
};
|
||||
}
|
||||
|
||||
requestPermission(): Promise<void> {
|
||||
return getNativeModule(this).requestPermission();
|
||||
}
|
||||
|
||||
/**
|
||||
* NON WEB-SDK METHODS
|
||||
*/
|
||||
deleteInstanceId(): Promise<void> {
|
||||
return getNativeModule(this).deleteInstanceId();
|
||||
}
|
||||
|
||||
getBadgeNumber(): Promise<number> {
|
||||
return getNativeModule(this).getBadgeNumber();
|
||||
}
|
||||
|
||||
getInitialMessage(): Promise<Message> {
|
||||
return getNativeModule(this).getInitialMessage();
|
||||
}
|
||||
|
||||
sendMessage(remoteMessage: RemoteMessage): Promise<void> {
|
||||
return getNativeModule(this).send(remoteMessage);
|
||||
}
|
||||
|
||||
setBadgeNumber(badge: number): void {
|
||||
getNativeModule(this).setBadgeNumber(badge);
|
||||
}
|
||||
|
||||
subscribeToTopic(topic: string): void {
|
||||
getNativeModule(this).subscribeToTopic(topic);
|
||||
}
|
||||
|
||||
unsubscribeFromTopic(topic: string): void {
|
||||
getNativeModule(this).unsubscribeFromTopic(topic);
|
||||
}
|
||||
|
||||
/**
|
||||
* KNOWN UNSUPPORTED METHODS
|
||||
*/
|
||||
|
||||
setBackgroundMessageHandler() {
|
||||
throw new Error(
|
||||
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
|
||||
'messaging',
|
||||
'setBackgroundMessageHandler'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
useServiceWorker() {
|
||||
throw new Error(
|
||||
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
|
||||
'messaging',
|
||||
'useServiceWorker'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const statics = {
|
||||
// RemoteMessage,
|
||||
};
|
|
@ -108,19 +108,24 @@ export default class Notifications extends ModuleBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove a delivered notification - using '*' will remove
|
||||
* all delivered notifications.
|
||||
* Remove a delivered notification.
|
||||
* @param id
|
||||
* @returns {*}
|
||||
*/
|
||||
removeDeliveredNotification(id: string): Promise<void> {
|
||||
if (!id) return Promise.reject(new Error('Missing notification id'));
|
||||
if (id === '*') {
|
||||
return getNativeModule(this).removeAllDeliveredNotifications();
|
||||
}
|
||||
return getNativeModule(this).removeDeliveredNotification(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all delivered notifications.
|
||||
* @param id
|
||||
* @returns {*}
|
||||
*/
|
||||
removeDeliveredNotifications(): Promise<void> {
|
||||
return getNativeModule(this).removeDeliveredNotifications();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param notification
|
||||
|
@ -136,3 +141,5 @@ export default class Notifications extends ModuleBase {
|
|||
return getNativeModule(this).scheduleLocalNotification(_notification);
|
||||
}
|
||||
}
|
||||
|
||||
export const statics = {};
|
|
@ -15,12 +15,14 @@ import type Database from '../modules/database';
|
|||
import { typeof statics as DatabaseStatics } from '../modules/database';
|
||||
import type Firestore from '../modules/firestore';
|
||||
import { typeof statics as FirestoreStatics } from '../modules/firestore';
|
||||
import type InstanceId from '../modules/instanceid';
|
||||
import { typeof statics as InstanceIdStatics } from '../modules/instanceid';
|
||||
import type Links from '../modules/links';
|
||||
import { typeof statics as LinksStatics } from '../modules/links';
|
||||
import type Messaging from '../modules/messaging';
|
||||
import { typeof statics as MessagingStatics } from '../modules/messaging';
|
||||
import type NewMessaging from '../modules/messaging/messagingIndex';
|
||||
import { typeof statics as NewMessagingStatics } from '../modules/messaging/messagingIndex';
|
||||
import type Notifications from '../modules/notifications';
|
||||
import { typeof statics as NotificationsStatics } from '../modules/notifications';
|
||||
import type ModuleBase from '../utils/ModuleBase';
|
||||
import type Performance from '../modules/perf';
|
||||
import { typeof statics as PerformanceStatics } from '../modules/perf';
|
||||
|
@ -58,9 +60,9 @@ export type FirebaseModuleName =
|
|||
| 'RNFirebaseCrashlytics'
|
||||
| 'RNFirebaseDatabase'
|
||||
| 'RNFirebaseFirestore'
|
||||
| 'RNFirebaseInstanceId'
|
||||
| 'RNFirebaseLinks'
|
||||
| 'RNFirebaseMessaging'
|
||||
| 'NewRNFirebaseMessaging'
|
||||
| 'RNFirebaseNotifications'
|
||||
| 'RNFirebasePerformance'
|
||||
| 'RNFirebaseStorage'
|
||||
|
@ -75,9 +77,9 @@ export type FirebaseNamespace =
|
|||
| 'crashlytics'
|
||||
| 'database'
|
||||
| 'firestore'
|
||||
| 'instanceid'
|
||||
| 'links'
|
||||
| 'messaging'
|
||||
| 'newmessaging'
|
||||
| 'notifications'
|
||||
| 'perf'
|
||||
| 'storage'
|
||||
|
@ -209,6 +211,13 @@ export type FirestoreWriteOptions = {
|
|||
merge?: boolean,
|
||||
};
|
||||
|
||||
/* InstanceId types */
|
||||
|
||||
export type InstanceIdModule = {
|
||||
(): InstanceId,
|
||||
nativeModuleExists: boolean,
|
||||
} & InstanceIdStatics;
|
||||
|
||||
/* Links types */
|
||||
|
||||
export type LinksModule = {
|
||||
|
@ -223,10 +232,12 @@ export type MessagingModule = {
|
|||
nativeModuleExists: boolean,
|
||||
} & MessagingStatics;
|
||||
|
||||
export type NewMessagingModule = {
|
||||
(): NewMessaging,
|
||||
/* Notifications types */
|
||||
|
||||
export type NotificationsModule = {
|
||||
(): Notifications,
|
||||
nativeModuleExists: boolean,
|
||||
} & NewMessagingStatics;
|
||||
} & NotificationsStatics;
|
||||
|
||||
/* Performance types */
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/AppTheme">
|
||||
<service
|
||||
android:name="io.invertase.firebase.messaging.MessagingService"
|
||||
android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
|
@ -24,7 +24,7 @@
|
|||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service android:name="io.invertase.firebase.messaging.InstanceIdService" android:exported="false">
|
||||
<service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
|
||||
</intent-filter>
|
||||
|
@ -34,6 +34,7 @@
|
|||
android:name=".MainActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTop"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -42,5 +43,4 @@
|
|||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.invertase.firebase.crash.RNFirebaseCrashPackage;
|
|||
import io.invertase.firebase.database.RNFirebaseDatabasePackage;
|
||||
import io.invertase.firebase.fabric.crashlytics.RNFirebaseCrashlyticsPackage;
|
||||
import io.invertase.firebase.firestore.RNFirebaseFirestorePackage;
|
||||
import io.invertase.firebase.instanceid.RNFirebaseInstanceIdPackage;
|
||||
import io.invertase.firebase.links.RNFirebaseLinksPackage;
|
||||
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
|
||||
import io.invertase.firebase.perf.RNFirebasePerformancePackage;
|
||||
|
@ -47,6 +48,7 @@ public class MainApplication extends Application implements ReactApplication {
|
|||
new RNFirebaseCrashlyticsPackage(),
|
||||
new RNFirebaseDatabasePackage(),
|
||||
new RNFirebaseFirestorePackage(),
|
||||
new RNFirebaseInstanceIdPackage(),
|
||||
new RNFirebaseLinksPackage(),
|
||||
new RNFirebaseMessagingPackage(),
|
||||
new RNFirebasePerformancePackage(),
|
||||
|
|
|
@ -7,19 +7,30 @@ import DatabaseContents from './tests/support/DatabaseContents';
|
|||
RNfirebase.database.enableLogging(true);
|
||||
RNfirebase.firestore.enableLogging(true);
|
||||
|
||||
RNfirebase.newmessaging()
|
||||
.requestPermission()
|
||||
.then(response => {
|
||||
console.log('requestPermission:', response);
|
||||
RNfirebase.newmessaging()
|
||||
.getToken()
|
||||
.then(token => {
|
||||
console.log('token: ', token);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('requestPermission:', error);
|
||||
});
|
||||
RNfirebase.messaging().onMessage(message => {
|
||||
console.log('got new message: ', message);
|
||||
});
|
||||
|
||||
RNfirebase.messaging().onTokenRefresh(token => {
|
||||
console.log('got new token: ', token);
|
||||
});
|
||||
|
||||
const init = async () => {
|
||||
try {
|
||||
await RNfirebase.messaging().requestPermission();
|
||||
const instanceid = await RNfirebase.instanceid().get();
|
||||
console.log('instanceid: ', instanceid);
|
||||
const token = await RNfirebase.messaging().getToken();
|
||||
console.log('token: ', token);
|
||||
const initialMessage = await RNfirebase.messaging().getInitialMessage();
|
||||
console.log('initial message: ', initialMessage);
|
||||
// RNfirebase.instanceid().delete();
|
||||
} catch (error) {
|
||||
console.error('messaging init error:', error);
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
|
||||
const config = {
|
||||
apiKey: 'AIzaSyDnVqNhxU0Biit9nCo4RorAh5ulQQwko3E',
|
||||
|
|
Loading…
Reference in New Issue