2021-10-29 21:13:58 -04:00
|
|
|
package io.heckel.ntfy.msg
|
|
|
|
|
|
|
|
import android.app.NotificationChannel
|
|
|
|
import android.app.NotificationManager
|
|
|
|
import android.content.Context
|
|
|
|
import android.media.RingtoneManager
|
|
|
|
import android.os.Build
|
|
|
|
import android.util.Log
|
|
|
|
import androidx.core.app.NotificationCompat
|
|
|
|
import com.google.firebase.messaging.FirebaseMessagingService
|
|
|
|
import com.google.firebase.messaging.RemoteMessage
|
|
|
|
import io.heckel.ntfy.R
|
|
|
|
import io.heckel.ntfy.data.Database
|
|
|
|
import io.heckel.ntfy.data.Repository
|
|
|
|
import io.heckel.ntfy.data.topicShortUrl
|
|
|
|
import kotlinx.coroutines.CoroutineScope
|
|
|
|
import kotlinx.coroutines.SupervisorJob
|
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
import kotlin.random.Random
|
|
|
|
|
|
|
|
class MessagingService : FirebaseMessagingService() {
|
|
|
|
private val database by lazy { Database.getInstance(this) }
|
|
|
|
private val repository by lazy { Repository.getInstance(database.subscriptionDao()) }
|
|
|
|
private val job = SupervisorJob()
|
|
|
|
|
|
|
|
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
|
|
|
// We only process data messages
|
|
|
|
if (remoteMessage.data.isEmpty()) {
|
|
|
|
Log.d(TAG, "Discarding unexpected message: from=${remoteMessage.from}")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if valid data, and send notification
|
|
|
|
val data = remoteMessage.data
|
|
|
|
val topic = data["topic"]
|
|
|
|
val message = data["message"]
|
|
|
|
if (topic == null || message == null) {
|
|
|
|
Log.d(TAG, "Discarding unexpected message: from=${remoteMessage.from}, data=${data}")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
CoroutineScope(job).launch {
|
|
|
|
val baseUrl = getString(R.string.app_base_url) // Everything from Firebase comes from main service URL!
|
|
|
|
|
|
|
|
// Update message counter
|
|
|
|
val subscription = repository.get(baseUrl, topic) ?: return@launch
|
|
|
|
val newSubscription = subscription.copy(messages = subscription.messages + 1)
|
|
|
|
repository.update(newSubscription)
|
|
|
|
|
|
|
|
// Send notification
|
|
|
|
Log.d(TAG, "Sending notification for message: from=${remoteMessage.from}, data=${data}")
|
|
|
|
val title = topicShortUrl(baseUrl, topic)
|
|
|
|
sendNotification(title, message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onNewToken(token: String) {
|
|
|
|
// Called if the FCM registration token is updated
|
|
|
|
// We don't actually use or care about the token, since we're using topics
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onDestroy() {
|
|
|
|
super.onDestroy()
|
|
|
|
job.cancel()
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun sendNotification(title: String, message: String) {
|
|
|
|
val channelId = getString(R.string.notification_channel_id)
|
|
|
|
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
|
|
|
val notificationBuilder = NotificationCompat.Builder(this, channelId)
|
2021-10-30 19:38:45 -04:00
|
|
|
.setSmallIcon(R.drawable.ic_notification_icon)
|
2021-10-29 21:13:58 -04:00
|
|
|
.setContentTitle(title)
|
|
|
|
.setContentText(message)
|
|
|
|
.setSound(defaultSoundUri)
|
|
|
|
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
|
val channelName = getString(R.string.notification_channel_name)
|
|
|
|
val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT)
|
|
|
|
notificationManager.createNotificationChannel(channel)
|
|
|
|
}
|
|
|
|
notificationManager.notify(Random.nextInt(), notificationBuilder.build())
|
|
|
|
}
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
private const val TAG = "NtfyFirebase"
|
|
|
|
}
|
|
|
|
}
|