Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove fallback code for FCM pre-21.0.0 #2148

Merged
merged 1 commit into from
Jul 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ import com.google.firebase.messaging.FirebaseMessaging
import com.onesignal.core.internal.application.IApplicationService
import com.onesignal.core.internal.config.ConfigModelStore
import com.onesignal.core.internal.device.IDeviceService
import com.onesignal.debug.internal.logging.Logging
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.IOException
import java.lang.reflect.InvocationTargetException
import java.util.concurrent.ExecutionException

internal class PushRegistratorFCM(
Expand Down Expand Up @@ -53,92 +46,32 @@ internal class PushRegistratorFCM(
this.apiKey = fcpParams.apiKey ?: defaultApiKey
}

@Throws(ExecutionException::class, InterruptedException::class, IOException::class)
@Throws(ExecutionException::class, InterruptedException::class)
override suspend fun getToken(senderId: String): String {
initFirebaseApp(senderId)
try {
return getTokenWithClassFirebaseMessaging()
} catch (e: NoClassDefFoundError) {
// Class or method wil be missing at runtime if firebase-message older than 21.0.0 is used.
Logging.info("FirebaseMessaging.getToken not found, attempting to use FirebaseInstanceId.getToken")
} catch (e: NoSuchMethodError) {
Logging.info("FirebaseMessaging.getToken not found, attempting to use FirebaseInstanceId.getToken")
}

// Fallback for firebase-message versions older than 21.0.0
return getTokenWithClassFirebaseInstanceId(senderId)
return getTokenWithClassFirebaseMessaging()
}

// This method is only used if firebase-message older than 21.0.0 is in the app
// We are using reflection here so we can compile with firebase-message:22.0.0 and newer
// - This version of Firebase has completely removed FirebaseInstanceId
@Deprecated("")
@Throws(IOException::class)
private suspend fun getTokenWithClassFirebaseInstanceId(senderId: String): String =
coroutineScope {
var token: String = ""
// The following code is equivalent to:
// FirebaseInstanceId instanceId = FirebaseInstanceId.getInstance(firebaseApp);
// return instanceId.getToken(senderId, FirebaseMessaging.INSTANCE_ID_SCOPE);
val exception: Exception =
try {
val firebaseInstanceIdClass = Class.forName("com.google.firebase.iid.FirebaseInstanceId")
val getInstanceMethod = firebaseInstanceIdClass.getMethod("getInstance", FirebaseApp::class.java)
val instanceId = getInstanceMethod.invoke(null, firebaseApp)
val getTokenMethod = instanceId.javaClass.getMethod("getToken", String::class.java, String::class.java)

launch(Dispatchers.Default) {
val tkn = getTokenMethod.invoke(instanceId, senderId, "FCM")
token = tkn as String
}

return@coroutineScope token
} catch (e: ClassNotFoundException) {
e
} catch (e: NoSuchMethodException) {
e
} catch (e: IllegalAccessException) {
e
} catch (e: InvocationTargetException) {
e
}

throw Error(
"Reflection error on FirebaseInstanceId.getInstance(firebaseApp).getToken(senderId, FirebaseMessaging.INSTANCE_ID_SCOPE)",
exception,
)
}

// We use firebaseApp.get(FirebaseMessaging.class) instead of FirebaseMessaging.getInstance()
// as the latter uses the default Firebase app. We need to use a custom Firebase app as
// the senderId is provided at runtime.
@Throws(ExecutionException::class, InterruptedException::class)
private suspend fun getTokenWithClassFirebaseMessaging(): String =
coroutineScope {
var token: String = ""

withContext(Dispatchers.Default) {
// FirebaseMessaging.getToken API was introduced in firebase-messaging:21.0.0
// We use firebaseApp.get(FirebaseMessaging.class) instead of FirebaseMessaging.getInstance()
// as the latter uses the default Firebase app. We need to use a custom Firebase app as
// the senderId is provided at runtime.
val fcmInstance = firebaseApp!!.get(FirebaseMessaging::class.java)
// FirebaseMessaging.getToken API was introduced in firebase-messaging:21.0.0
val tokenTask = fcmInstance.token
try {
token = Tasks.await(tokenTask)
} catch (e: ExecutionException) {
throw tokenTask.exception ?: e
}
}

return@coroutineScope token
private fun getTokenWithClassFirebaseMessaging(): String {
// We use firebaseApp.get(FirebaseMessaging.class) instead of FirebaseMessaging.getInstance()
// as the latter uses the default Firebase app. We need to use a custom Firebase app as
// the senderId is provided at runtime.
val fcmInstance = firebaseApp!!.get(FirebaseMessaging::class.java)
// FirebaseMessaging.getToken API was introduced in firebase-messaging:21.0.0
val tokenTask = fcmInstance.token
try {
return Tasks.await(tokenTask)
} catch (e: ExecutionException) {
throw tokenTask.exception ?: e
}
}

private fun initFirebaseApp(senderId: String) {
if (firebaseApp != null) return
val firebaseOptions =
FirebaseOptions.Builder()
FirebaseOptions
.Builder()
.setGcmSenderId(senderId)
.setApplicationId(appId)
.setApiKey(apiKey)
Expand Down
Loading