Skip to content
This repository has been archived by the owner on Sep 14, 2024. It is now read-only.

Commit

Permalink
feat: add initial android implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
gtokman committed Apr 17, 2024
1 parent c83d1b7 commit 25bb53b
Show file tree
Hide file tree
Showing 7 changed files with 631 additions and 201 deletions.
2 changes: 2 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def isNewArchitectureEnabled() {

apply plugin: "com.android.library"
apply plugin: "kotlin-android"
apply plugin: 'kotlin-parcelize'

if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
Expand Down Expand Up @@ -92,5 +93,6 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation(platform("com.google.firebase:firebase-bom:32.7.2"))
implementation "com.google.firebase:firebase-messaging"
implementation 'androidx.core:core-ktx:1.12.0'
}

2 changes: 2 additions & 0 deletions android/src/main/AndroidManifestNew.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application>
<service
android:exported="false"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,82 +1,92 @@
package com.candlefinance.push

import android.content.Intent
import android.os.Bundle
import android.util.Log
import com.facebook.react.HeadlessJsTaskService
import com.facebook.react.bridge.Arguments
import com.facebook.react.jstasks.HeadlessJsTaskConfig
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import org.json.JSONObject
import java.lang.Exception
import java.util.UUID

class FirebaseMessagingService : FirebaseMessagingService() {
private val TAG = PushModule::class.java.simpleName
class PushNotificationHeadlessTaskService : HeadlessJsTaskService() {

override fun onSendError(msgId: String, exception: Exception) {
super.onSendError(msgId, exception)
RNEventEmitter.sendEvent(errorReceived, exception.message)
}
private val defaultTimeout: Long = 10000 // 10 seconds
override fun getTaskConfig(intent: Intent): HeadlessJsTaskConfig? {
return NotificationPayload.fromIntent(intent)?.let {
HeadlessJsTaskConfig(
HEADLESS_TASK_KEY,
Arguments.createMap().apply {
putString("content", it.rawData.toString())
},
defaultTimeout, true
)
}
}

override fun onMessageReceived(remoteMessage: RemoteMessage) {
val title = remoteMessage.notification?.title.toString()
val body = remoteMessage.notification?.body.toString()
companion object {
const val HEADLESS_TASK_KEY = "PushNotificationHeadlessTaskKey"
}
}

val formattedData = JSONObject()
class FirebaseMessagingService : FirebaseMessagingService() {

val apsData = JSONObject()
apsData.put("alert", JSONObject().apply {
put("title", title)
put("body", body)
})
formattedData.put("payload", JSONObject().apply {
put("aps", apsData)
put("custom", JSONObject(mapToString(remoteMessage.data)))
})
private lateinit var utils: PushNotificationUtils

formattedData.put("kind", getAppState())
formattedData.put("uuid", UUID.randomUUID().toString())
override fun onCreate() {
super.onCreate()
utils = PushNotificationUtils(baseContext)
}

// Send the event
RNEventEmitter.sendEvent(notificationReceived, formattedData.toString())
ContextHolder.getInstance().getApplicationContext()?.let {
NotificationUtils
.sendNotification(
it, title, body
)
}
if (remoteMessage.data.isNotEmpty()) {
Log.d(TAG, "Message data payload: ${remoteMessage.data}")
}
remoteMessage.notification?.let {
Log.d(TAG, "Message Notification Body: ${it.body}")
}
override fun onNewToken(token: String) {
super.onNewToken(token)
val params = Arguments.createMap()
params.putString("token", token)
Log.d(TAG, "Send device token event")
PushNotificationEventManager.sendEvent(PushNotificationEventType.TOKEN_RECEIVED, params)
}

private fun mapToString(map: Map<String, String>): String {
val json = JSONObject()
for ((key, value) in map) {
json.put(key, value)
override fun handleIntent(intent: Intent) {
val extras = intent.extras ?: Bundle()
extras.getString("gcm.notification.body")?.let {
// Use the notification body here
// message contains push notification payload, show notification
// onMessageReceived(it)
Log.d(TAG, "**** Message: ${it}")
} ?: run {
Log.d(TAG, "Ignore intents that don't contain push notification payload")
super.handleIntent(intent)
}
return json.toString()
}

// TODO: make this actually work
private fun getAppState(): String {
val reactContext = ContextHolder.getInstance().getApplicationContext()
val currentActivity = reactContext?.currentActivity
return if (currentActivity == null) {
"background"
private fun onMessageReceived(payload: NotificationPayload) {
if (utils.isAppInForeground()) {
Log.d(TAG, "Send foreground message received event")
PushNotificationEventManager.sendEvent(
PushNotificationEventType.FOREGROUND_MESSAGE_RECEIVED, Arguments.createMap().apply {
putString("content", payload.rawData.toString())
}
)
} else {
"foreground"
}
}
Log.d(
TAG, "App is in background, try to create notification and start headless service"
)

override fun onNewToken(token: String) {
Log.d(TAG,token)
RNEventEmitter.sendEvent(deviceTokenReceived, token)
}
utils.showNotification(payload)

companion object {
private const val TAG = "MyFirebaseMsgService"
const val notificationReceived = "notificationReceived"
const val deviceTokenReceived = "deviceTokenReceived"
const val errorReceived = "errorReceived"
try {
val serviceIntent =
Intent(baseContext, PushNotificationHeadlessTaskService::class.java)
serviceIntent.putExtra("NotificationPayload", payload)
if (baseContext.startService(serviceIntent) != null) {
HeadlessJsTaskService.acquireWakeLockNow(baseContext)
}
} catch (exception: Exception) {
Log.e(
TAG, "Something went wrong while starting headless task: ${exception.message}"
)
}
}
}

}
Loading

0 comments on commit 25bb53b

Please sign in to comment.