Hello to all in community. I get message from title of this post during executing RUN command in my app.
First .kt file (MyTaxiApplication.kt):
package com.innomalist.taxi.common
import android.app.Activity
import android.app.Application
import androidx.appcompat.app.AppCompatDelegate
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ProcessLifecycleOwner
import com.google.firebase.FirebaseApp
import com.google.firebase.iid.FirebaseInstanceId
import com.innomalist.taxi.common.components.BaseActivity
import com.innomalist.taxi.common.networking.socket.interfaces.ConnectionError
import com.innomalist.taxi.common.networking.socket.interfaces.RemoteResponse
import com.innomalist.taxi.common.networking.socket.interfaces.SocketNetworkDispatcher
import com.innomalist.taxi.common.utils.AlertDialogBuilder
import com.innomalist.taxi.common.utils.LoadingDialog
import com.innomalist.taxi.common.utils.MyPreferenceManager
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class MyTaxiApplication: Application(), LifecycleObserver {
private var currentActivity: BaseActivity? = null
override fun onCreate() {
FirebaseApp.initializeApp(applicationContext)
val nightMode = AppCompatDelegate.MODE_NIGHT_NO
AppCompatDelegate.setDefaultNightMode(nightMode)
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
super.onCreate()
}
fun getCurrentActivity(): Activity {
return currentActivity!!
}
fun setCurrentActivity(mCurrentActivity: BaseActivity?) {
currentActivity = mCurrentActivity
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onMoveToForeground() {
if(currentActivity is BaseActivity && !(currentActivity as BaseActivity).shouldReconnect) return
val token = MyPreferenceManager.getInstance(this).token ?: return
if(SocketNetworkDispatcher.currentNamespace == null) return
if(currentActivity != null) LoadingDialog.display(currentActivity!!)
FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { fb ->
SocketNetworkDispatcher.instance.connect(SocketNetworkDispatcher.currentNamespace!!, token, fb.result!!.token) {
when(it) {
is RemoteResponse.Success -> {
LoadingDialog.hide()
currentActivity?.onReconnected()
}
is RemoteResponse.Error -> {
GlobalScope.launch(Main) {
if(it.error == ConnectionError.TokenVerificationError)
return@launch
AlertDialogBuilder.show(currentActivity!!, getString(R.string.error_message_reconnection_failed, it.error.rawValue),AlertDialogBuilder.DialogButton.OK) {
currentActivity!!.finishAffinity()
}
}
}
}
}
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onMoveToBackground() {
SocketNetworkDispatcher.instance.disconnect()
}
}
Second .kt file (SocketNetworkDispatcher.kt):
package com.innomalist.taxi.common.networking.socket.interfaces
import android.content.Context
import android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR
import android.util.Log
import com.google.android.gms.maps.model.LatLng
import com.innomalist.taxi.common.Config
import com.innomalist.taxi.common.models.ChatMessage
import com.innomalist.taxi.common.models.Request
import com.innomalist.taxi.common.utils.Adapters
import com.innomalist.taxi.common.utils.AlertDialogBuilder
import com.squareup.moshi.Json
import io.socket.client.IO
import io.socket.client.Manager.EVENT_ERROR
import io.socket.client.Socket
import io.socket.engineio.client.Socket.EVENT_ERROR
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.JSONObject
class SocketNetworkDispatcher : NetworkDispatcher {
companion object {
var instance = SocketNetworkDispatcher()
var currentNamespace: Namespace? = null
}
var socket: Socket? = null
var onNewMessage: ((ChatMessage) -> Unit)? = null
var onArrived: ((Int) -> Unit)? = null
var onStarted: ((Request) -> Unit)? = null
var onTravelInfo: ((LatLng) -> Unit)? = null
var onNewRequest: ((Request) -> Unit)? = null
var onFinished: ((FinishResult) -> Unit)? = null
var onCancel: ((Int) -> Unit)? = null
var onCancelRequest: ((Int) -> Unit)? = null
var onDriverAccepted: ((Request) -> Unit)? = null
var onPaid: ((Int) -> Unit)? = null
override fun dispatch(event: String, params: Array<Any>?, completionHandler: (RemoteResponse<Any, SocketClientError>) -> Unit) {
if(socket == null) {
return
}
socket!!.emit(event, params) {
if ((it.size > 1)) {
completionHandler(RemoteResponse.createError(SocketClientError.InvalidAckParamCount))
return@emit
}
if ((it.isEmpty())) {
GlobalScope.launch(Dispatchers.Main) {
completionHandler(RemoteResponse.createSuccess(EmptyClass()))
}
return@emit
}
completionHandler(RemoteResponse.createSuccess(it[0]))
}
}
fun connect(namespace: Namespace, token: String, notificationId: String, completionHandler: (RemoteResponse<Boolean, ConnectionError>) -> Unit) {
val options = IO.Options()
currentNamespace = namespace
options.reconnection = true
options.query = "token=$token&os=android&ver=60¬=$notificationId"
socket = IO.socket("${Config.Backend}${namespace.rawValue}", options)
socket!!.on(Socket.EVENT_CONNECT) {
completionHandler(RemoteResponse.createSuccess(true))
}
val on = socket!!.on(Socket.EVENT_ERROR) {
//socket!!.disconnect()
if (it.isEmpty()) {
completionHandler(RemoteResponse.createError(ConnectionError.ErrorWithoutData))
} else if (it[0] is JSONObject) {
Log.e("Error message", (it[0] as JSONObject)["message"] as String)
completionHandler(RemoteResponse.createError(ConnectionError.TokenVerificationError))
} else if (it[0] is String) {
val knownError = ConnectionError(rawValue = it[0] as String)
if (knownError != null) {
completionHandler(RemoteResponse.createError(knownError))
} else {
completionHandler(RemoteResponse.createError(ConnectionError.Unknown))
}
} else {
completionHandler(RemoteResponse.createError(ConnectionError.NotDecodableError))
}
}
socket!!.on("cancelRequest") { item ->
GlobalScope.launch(Dispatchers.Main) {
onCancelRequest?.invoke(item[0] as Int)
}
}
// Driver Events
socket!!.on("requestReceived") { item ->
val travel = Adapters.moshi.adapter(Request::class.java).fromJson(item[0].toString())
GlobalScope.launch(Dispatchers.Main) {
onNewRequest?.invoke(travel!!)
}
}
socket!!.on("messageReceived") { item ->
val message = Adapters.moshi.adapter<ChatMessage>(ChatMessage::class.java).fromJson(item[0].toString())
onNewMessage?.invoke(message!!)
}
socket!!.on("cancelTravel") {
GlobalScope.launch(Dispatchers.Main) {
onCancel?.invoke(0)
}
}
socket!!.on("paid") {
GlobalScope.launch(Dispatchers.Main) {
onPaid?.invoke(0)
}
}
socket!!.on("arrived") {
GlobalScope.launch(Dispatchers.Main) {
onArrived?.invoke(0)
}
}
socket!!.on("started") { item ->
val travel = Adapters.moshi.adapter<Request>(Request::class.java).fromJson(item[0].toString())
GlobalScope.launch(Dispatchers.Main) {
onStarted?.invoke(travel!!)
}
}
socket!!.on("travelInfoReceived") { item ->
val json = item[0] as JSONObject
val lng = json.getDouble("x")
val lat = json.getDouble("y")
val loc = LatLng(lat, lng)
GlobalScope.launch(Dispatchers.Main) {
onTravelInfo?.invoke(loc)
}
}
socket!!.on("Finished") { item ->
GlobalScope.launch(Dispatchers.Main) {
if(item[1] is Int) {
onFinished?.invoke(FinishResult(item[0] as Boolean, (item[1] as Int).toDouble()))
} else {
onFinished?.invoke(FinishResult(item[0] as Boolean, item[1] as Double))
}
}
}
socket!!.on("driverAccepted") { item ->
val travel = Adapters.moshi.adapter<Request>(Request::class.java).fromJson(item[0].toString())
GlobalScope.launch(Dispatchers.Main) {
onDriverAccepted?.invoke(travel!!)
}
}
socket!!.connect()
}
fun disconnect() {
socket?.disconnect()
}
}
enum class Namespace(val rawValue: String) {
Driver("drivers"), Rider("riders")
}
enum class ConnectionError(val rawValue: String) {
@Json(name = "VersionOutdated")
VersionOutdated("VersionOutdated"),
@Json(name="NotFound")
NotFound("NotFound"),
@Json(name="NotFound")
Blocked("Blocked"),
@Json(name="RegistrationIncomplete")
RegistrationIncomplete("RegistrationIncomplete"),
@Json(name="TokenVerificationError")
TokenVerificationError("TokenVerificationError"),
@Json(name="NotDecodableError")
NotDecodableError("NotDecodableError"),
@Json(name="Unknown")
Unknown("Unknown"),
@Json(name="ErrorWithoutData")
ErrorWithoutData("ErrorWithoutData");
fun showAlert(context: Context) {
AlertDialogBuilder.show(context, this.toString(), AlertDialogBuilder.DialogButton.OK, null)
}
companion object {
operator fun invoke(rawValue: String) = values().firstOrNull { it.rawValue == rawValue }
}
}
data class FinishResult(
val paid: Boolean,
val remainingAmount: Double
)
enum class SocketClientError(val rawValue: String) {
InvalidAckParamCount("InvalidAckParamCount"), RequestTimeout("RequestTimeout");
companion object {
operator fun invoke(rawValue: String) = values().firstOrNull { it.rawValue == rawValue }
}
val localizedDescription: String
get() {
return when (this) {
InvalidAckParamCount -> "Result parameter count is more than one. It's unexpected."
RequestTimeout -> "Request Timeout"
}
}
}
DEBUG - ERROR Screeenshoot:

app-level build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.4.31'
repositories {
maven { url "https://maven.google.com" }
jcenter()
google()
maven { url 'https://plugins.gradle.org/m2/'}
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.3'
classpath 'com.google.gms:google-services:4.3.8'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.6.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
maven { url "https://maven.google.com" }
jcenter()
mavenCentral()
google()
maven { url "https://jitpack.io" }
maven {
url "https://cardinalcommerce.bintray.com/android"
credentials {
username 'braintree-team-sdk@cardinalcommerce'
password '220cc9476025679c4e5c843666c27d97cfb0f951'
}
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
I know this is depreciated, and that I need to replace depreciated with Firebase Installation or Messaging - but I really don't have a clue from where to strat, because this is not my code, I bought this and developers just vanished and left me with this.
I'm not good in Android/Kotlin development, but I'm web developer - so any guidance will do me good.
Thank you very much all...
EDIT
I tried import of dependencies related to firebase messaging and installation and tried to replace obsolete code with suggestions from Firebase documentation, but every time I get another, new error.
FirebaseInstanceId is depricated, you can read more here
Firebase Instance ID has been replaced with FirebaseInstallations for app instance identifiers and FirebaseMessaging.getToken() for FCM registration tokens.
That said, replace this
FirebaseInstanceId.getInstance().instanceId with FirebaseInstallations.getInstance().id. Your First.kt will be updated to:
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onMoveToForeground() {
if(currentActivity is BaseActivity && !(currentActivity as BaseActivity).shouldReconnect) return
val token = MyPreferenceManager.getInstance(this).token ?: return
if(SocketNetworkDispatcher.currentNamespace == null) return
if(currentActivity != null) LoadingDialog.display(currentActivity!!)
// Replace FirebaseInstanceId with FirebaseInstallations
FirebaseInstallations.getInstance().id.addOnCompleteListener { fb ->
if (!fb.isSuccessful){
return@addOnCompleteListener
}
SocketNetworkDispatcher.instance.connect(SocketNetworkDispatcher.currentNamespace!!, token, fb.result) {
when(it) {
is RemoteResponse.Success -> {
LoadingDialog.hide()
currentActivity?.onReconnected()
}
is RemoteResponse.Error -> {
GlobalScope.launch(Main) {
if(it.error == ConnectionError.TokenVerificationError)
return@launch
AlertDialogBuilder.show(currentActivity!!, getString(R.string.error_message_reconnection_failed, it.error.rawValue),AlertDialogBuilder.DialogButton.OK) {
currentActivity!!.finishAffinity()
}
}
}
}
}
}
}
To get the token FirebaseInstallations.getInstance().getToken(false).result.token
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With