package io.fullstack.firestack; import java.util.Map; import android.content.Context; import android.content.IntentFilter; import android.content.Intent; import android.content.BroadcastReceiver; import android.util.Log; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMapKeySetIterator; import com.facebook.react.bridge.ReadableType; import com.facebook.react.bridge.WritableMap; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.RemoteMessage; /** * Created by nori on 2016/09/12. */ public class FirestackCloudMessaging extends ReactContextBaseJavaModule { private static final String TAG = "FirestackCloudMessaging"; private static final String EVENT_NAME_TOKEN = "FirestackRefreshToken"; private static final String EVENT_NAME_NOTIFICATION = "FirestackReceiveNotification"; private static final String EVENT_NAME_SEND = "FirestackUpstreamSend"; public static final String INTENT_NAME_TOKEN = "io.fullstack.firestack.refreshToken"; public static final String INTENT_NAME_NOTIFICATION = "io.fullstack.firestack.ReceiveNotification"; public static final String INTENT_NAME_SEND = "io.fullstack.firestack.Upstream"; private ReactContext mReactContext; private IntentFilter mRefreshTokenIntentFilter; private IntentFilter mReceiveNotificationIntentFilter; private IntentFilter mReceiveSendIntentFilter; public FirestackCloudMessaging(ReactApplicationContext reactContext) { super(reactContext); mReactContext = reactContext; mRefreshTokenIntentFilter = new IntentFilter(INTENT_NAME_TOKEN); mReceiveNotificationIntentFilter = new IntentFilter(INTENT_NAME_NOTIFICATION); mReceiveSendIntentFilter = new IntentFilter(INTENT_NAME_SEND); initRefreshTokenHandler(); initMessageHandler(); initSendHandler(); Log.d(TAG, "New instance"); } @Override public String getName() { return TAG; } @ReactMethod public void getToken(final Callback callback) { try { String token = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Firebase token: " + token); callback.invoke(null, token); } catch (Exception e) { WritableMap error = Arguments.createMap(); error.putString("message", e.getMessage()); callback.invoke(error); } } /** * */ private void initRefreshTokenHandler() { getReactApplicationContext().registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { WritableMap params = Arguments.createMap(); params.putString("token", intent.getStringExtra("token")); ReactContext ctx = getReactApplicationContext(); Log.d(TAG, "initRefreshTokenHandler received event " + EVENT_NAME_TOKEN); FirestackUtils.sendEvent(ctx, EVENT_NAME_TOKEN, params); } ; }, mRefreshTokenIntentFilter); } @ReactMethod public void subscribeToTopic(String topic, final Callback callback) { try { FirebaseMessaging.getInstance().subscribeToTopic(topic); callback.invoke(null,topic); } catch (Exception e) { e.printStackTrace(); Log.d(TAG, "Firebase token: " + e); WritableMap error = Arguments.createMap(); error.putString("message", e.getMessage()); callback.invoke(error); } } @ReactMethod public void unsubscribeFromTopic(String topic, final Callback callback) { try { FirebaseMessaging.getInstance().unsubscribeFromTopic(topic); callback.invoke(null,topic); } catch (Exception e) { WritableMap error = Arguments.createMap(); error.putString("message", e.getMessage()); callback.invoke(error); } } private void initMessageHandler() { Log.d(TAG, "Firestack initMessageHandler called"); getReactApplicationContext().registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { RemoteMessage remoteMessage = intent.getParcelableExtra("data"); Log.d(TAG, "Firebase onReceive: " + remoteMessage); WritableMap params = Arguments.createMap(); if (remoteMessage.getData().size() != 0) { WritableMap dataMap = Arguments.createMap(); Map<String, String> data = remoteMessage.getData(); //Set<String> keysIterator = data.keySet(); for (String key : data.keySet()) { dataMap.putString(key, data.get(key)); } params.putMap("data", dataMap); } else { params.putNull("data"); } if (remoteMessage.getNotification() != null) { WritableMap notificationMap = Arguments.createMap(); RemoteMessage.Notification notification = remoteMessage.getNotification(); notificationMap.putString("title", notification.getTitle()); notificationMap.putString("body", notification.getBody()); notificationMap.putString("icon", notification.getIcon()); notificationMap.putString("sound", notification.getSound()); notificationMap.putString("tag", notification.getTag()); params.putMap("notification", notificationMap); } else { params.putNull("notification"); } ReactContext ctx = getReactApplicationContext(); FirestackUtils.sendEvent(ctx, EVENT_NAME_NOTIFICATION, params); } }, mReceiveNotificationIntentFilter); } @ReactMethod public void send(String senderId, String messageId, String messageType, ReadableMap params, final Callback callback) { FirebaseMessaging fm = FirebaseMessaging.getInstance(); RemoteMessage.Builder remoteMessage = new RemoteMessage.Builder(senderId); remoteMessage.setMessageId(messageId); remoteMessage.setMessageType(messageType); ReadableMapKeySetIterator iterator = params.keySetIterator(); while (iterator.hasNextKey()) { String key = iterator.nextKey(); ReadableType type = params.getType(key); if (type == ReadableType.String) { remoteMessage.addData(key, params.getString(key)); Log.d(TAG, "Firebase send: " + key); Log.d(TAG, "Firebase send: " + params.getString(key)); } } try { fm.send(remoteMessage.build()); WritableMap res = Arguments.createMap(); res.putString("status", "success"); callback.invoke(null, res); } catch(Exception e) { Log.e(TAG, "Error sending message", e); WritableMap error = Arguments.createMap(); error.putString("code", e.toString()); error.putString("message", e.toString()); callback.invoke(error); } } private void initSendHandler() { getReactApplicationContext().registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { WritableMap params = Arguments.createMap(); if (intent.getBooleanExtra("hasError", false)) { WritableMap error = Arguments.createMap(); error.putInt("code", intent.getIntExtra("errCode", 0)); error.putString("message", intent.getStringExtra("errorMessage")); params.putMap("err", error); } else { params.putNull("err"); } ReactContext ctx = getReactApplicationContext(); FirestackUtils.sendEvent(ctx, EVENT_NAME_SEND, params); } }, mReceiveSendIntentFilter); } }