Skip to content

Commit

Permalink
Merge pull request #2148 from OneSignal/cleanup-pre-fcm-21-support
Browse files Browse the repository at this point in the history
Remove fallback code for FCM pre-21.0.0
  • Loading branch information
jkasten2 committed Jul 16, 2024
2 parents 4a70a39 + 918c0eb commit ec71f7e
Showing 1 changed file with 16 additions and 83 deletions.
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

0 comments on commit ec71f7e

Please sign in to comment.