Java.Lang.StackoverflowError при отправке пуш-уведомления
Прошу помощи. Сам не программист, просто пытаюсь написать приложение для своего маленького стартапа. при нажатии на кнопку приложение меняет данные в firebase realtime database и отправляет пуш-уведомление на другой телефон/приложение. На каких-то телефонах работает как надо, а на каких-то вылетает. Java.Lang.StackoverflowError. Думаю проблема либо в retrofit, либо в корутинах.
Интерфейс ретрофит с корутинами. Если закоментировать @Headers или @POST приложение не вылетает, но и пуш естественно не отправляется.
interface NotificationAPI {
@Headers("Authorization: key=$SERVER_KEY", "Content-Type:$CONTENT_TYPE")
@POST("fcm/send")
suspend fun postNotification(
@Body notification: PushNotification
): Response<ResponseBody>}
Код из активити с кнопкой.
override fun onNeSdelanoClick(work: SmetaFB) {
if (work.executor == execName) {
myRef.child(selectedCategory).child(work.id!!).child("executor").removeValue()
myRef.child(selectedCategory).child(work.id!!).child("sdelanoDate").removeValue()
myRef.child(selectedCategory).child(work.id!!).child("ogidaetRascheta").setValue(false)
val title = projName
val message = "$execName - Не сделал - ${work.workName} - в $roomName"
if (title.isNotEmpty() && message.isNotEmpty()) {
PushNotification(
Message(
title,
message,
projId,
roomId,
roomName,
selectedCategory,
work.workName!!
),
TOPIC_WORK
).also {
sendNotification(it)
}
}
} else Toast.makeText(
this, " Выполнил ${work.executor}. " +
"Обратитесь к руководителю.", Toast.LENGTH_LONG
).show()
}
private fun sendNotification(notification: PushNotification) = CoroutineScope(Dispatchers.IO).launch{
try {
val response = RetrofitInstance.api.postNotification(notification)
if (response.isSuccessful) {
Log.d(TAG, "Response: ${Gson().toJson(response)}")
} else {
Log.e(TAG, response.errorBody().toString())
}
} catch (e: Exception) {
Log.e(TAG, e.toString())
}
}
Ещё код от ретрофита.
class RetrofitInstance {
companion object {
private val retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
val api by lazy {
retrofit.create(NotificationAPI::class.java)
}
}
}
FireBase service.
private const val CHANNEL_ID = "WorkChanged"
private const val OTCHET_ID = "otchet"
class FirebaseService : FirebaseMessagingService() {
companion object {
var sharedPref: SharedPreferences? = null
var token: String?
get() {
return sharedPref?.getString("token", "")
}
set(value) {
sharedPref?.edit()?.putString("token", value)?.apply()
}
}
override fun onNewToken(newToken: String) {
super.onNewToken(newToken)
token = newToken
}
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
val intent = Intent(this, MainActivity::class.java)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notificationID = Random.nextInt()
createNotificationChannelWork(notificationManager)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent,
FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE)
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle(message.data["title"])
.setContentText(message.data["message"])
.setSmallIcon(android.R.mipmap.sym_def_app_icon)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.build()
notificationManager.notify(notificationID, notification)
}
private fun createNotificationChannelWork(notificationManager: NotificationManager) {
val channelName = "Изменение в работах"
val channel = NotificationChannel(CHANNEL_ID, channelName, IMPORTANCE_HIGH).apply {
description = ""
enableLights(true)
lightColor = Color.GREEN
}
notificationManager.createNotificationChannel(channel)
}
}
Манифест.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission
android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@drawable/vaex_icon_blue"
android:label="@string/app_name"
android:roundIcon="@drawable/vaex_icon_blue"
android:supportsRtl="true"
android:theme="@style/Theme.VaexExecutor"
tools:targetApi="31">
<activity
android:name=".ToolsActivity"
android:exported="false" />
<activity
android:name=".StartActivity"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<service
android:name=".notification.FirebaseService"
android:exported="true"
android:permission="com.google.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
<action android:name="com.google.android.c2dm.permission.intent.RECEIVE" />
</intent-filter>
</service>
Помогите чем сможете. Или тыкнете носом как можно реализовать пуши иначе, без ретрофита и корутин.