I'm trying to send a notification whenever I send a message, but the notification is not displaying even though the message is sent successfully. I have added the necessary dependency and I am also able to send notifications through Firebase.
Here are my getToken()
and sendNotification()
functions. In the sendNotification()
function, the log value for
Response.Listener { response: JSONObject -> Log.d("TAG", "onResponse: $response") }
is
D/TAG: onResponse: {"multicast_id":2648883838169160595,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
.
My receiverUid
is correct and I'm also able to retrieve the token for the receiver user, and my server key is correct as well.
What is wrong with my code?
Why isn't it working?
private fun getToken(message: String) {
receiverUid = intent.getStringExtra("uid")
val databaseReference = FirebaseDatabase.getInstance().getReference("user").child(receiverUid!!)
databaseReference.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val user = dataSnapshot.getValue(User::class.java)
if (dataSnapshot.exists()) {
val token = user?.token
val to = JSONObject()
to.put("to", token)
val data = JSONObject()
val uid = FirebaseAuth.getInstance().currentUser?.uid
val firebaseRef = FirebaseDatabase.getInstance().getReference("user").child(uid!!)
firebaseRef.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val user = dataSnapshot.getValue(User::class.java)
val myName = user?.name
val myId = user?.uid
val myImage = user?.profileImageUrl
val chatId = "${receiverUid}${uid}"
data.put("hisId", myId)
data.put("hisImage", myImage)
data.put("title", myName)
data.put("message", message)
data.put("chatId", chatId)
Log.d("hisToken",token.toString())
to.put("data", data)
sendNotification(to)
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
}
}
override fun onCancelled(error: DatabaseError) {
TODO("Not yet implemented")
}
})
}
private fun sendNotification(to: JSONObject) {
val request: JsonObjectRequest = object : JsonObjectRequest(
Method.POST,
Constants.NOTIFICATION_URL,
to,
Response.Listener { response: JSONObject ->
Log.d("TAG", "onResponse: $response")
},
Response.ErrorListener {
Log.d("TAG", "onError: $it")
}) {
override fun getHeaders(): MutableMap<String, String> {
val map: MutableMap<String, String> = HashMap()
map["Authorization"] = "key=" + Constants.SERVER_KEY
map["Content-type"] = "application/json"
return map
}
override fun getBodyContentType(): String {
return "application/json"
}
}
val requestQueue = Volley.newRequestQueue(this@ChatActivity)
request.retryPolicy = DefaultRetryPolicy(
30000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
)
requestQueue.add(request)
}
In my SplashActivity I'm retrieving the token as follow and it is saving the value in firebase database
val intent = Intent(this@SplashActivity, HomeMain::class.java)
FirebaseInstallations.getInstance().getToken(/* forceRefresh= */ true)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
val token = task.result?.token
val databaseReference =
FirebaseDatabase.getInstance().getReference("user")
.child(appUtil.getUID()!!)
val map: MutableMap<String, Any> = HashMap()
map["token"] = token!!
databaseReference.updateChildren(map)
}
startActivity(intent)
finish()
And my Firebase Messaging service Class is below
package com.example.chat
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Intent
import android.media.RingtoneManager
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import androidx.core.content.res.ResourcesCompat
import com.example.chat.bnNavigation.AppUtil
import com.example.chat.bnNavigation.Constants
import com.example.chat.bnNavigation.message.ChatActivity
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import java.util.*
import kotlin.collections.HashMap
class MyFirebaseMessagingService : FirebaseMessagingService() {
private val appUtil = AppUtil()
override fun onNewToken(token: String) {
super.onNewToken(token)
updateToken(token)
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
if (remoteMessage.data.isNotEmpty()) {
val map: Map<String, String> = remoteMessage.data
val hisId = map["hisId"]
val hisImage = map["hisImage"]
val title = map["title"]
val message = map["message"]
val chatId = map["chatId"]
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
createOreoNotification(title!!, message!!, hisId!!, hisImage!!, chatId!!)
else createNormalNotification(title!!, message!!, hisId!!, hisImage!!, chatId!!)
}
}
private fun updateToken(token: String) {
if(appUtil.getUID() != null) {
val databaseReference =
FirebaseDatabase.getInstance().getReference("user").child(appUtil.getUID()!!)
val map: MutableMap<String, Any> = HashMap()
map["token"] = token
databaseReference.updateChildren(map)
}
}
private fun createNormalNotification(
title: String,
message: String,
hisId: String,
hisImage: String,
chatId: String
) {
val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val builder = NotificationCompat.Builder(this, Constants.CHANNEL_ID)
builder.setContentTitle(title)
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setAutoCancel(true)
.setColor(ResourcesCompat.getColor(resources, R.color.black, null))
.setSound(uri)
val intent = Intent(this, ChatActivity::class.java)
intent.putExtra("hisId", hisId)
intent.putExtra("hisImage", hisImage)
intent.putExtra("chatId", chatId)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
builder.setContentIntent(pendingIntent)
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
manager.notify(Random().nextInt(85 - 65), builder.build())
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createOreoNotification(
title: String,
message: String,
hisId: String,
hisImage: String,
chatId: String
) {
val channel = NotificationChannel(
Constants.CHANNEL_ID,
"Message",
NotificationManager.IMPORTANCE_HIGH
)
channel.setShowBadge(true)
channel.enableLights(true)
channel.enableVibration(true)
channel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(channel)
val intent = Intent(this, ChatActivity::class.java)
intent.putExtra("hisId", hisId)
intent.putExtra("hisImage", hisImage)
intent.putExtra("chatId", chatId)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
val notification = Notification.Builder(this, Constants.CHANNEL_ID)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setAutoCancel(true)
.setColor(ResourcesCompat.getColor(resources, R.color.gradEnd, null))
.setContentIntent(pendingIntent)
.build()
manager.notify(100, notification)
}
}