Skip to content

[Bug]: 5.4.0 - PermissionsViewModel.executeCallback - java.lang.NullPointerException #2410

@niksstepup

Description

@niksstepup

What happened?

I am seeing this crash faced by 22 users ~48 events on our app


Fatal Exception: java.lang.NullPointerException:
       at com.onesignal.core.internal.permissions.PermissionsViewModel.executeCallback(PermissionsViewModel.kt:153)

Steps to reproduce?

None, I see this is reported as fatal in my firebase crashlytics. 

Only i see in logs and breadcrumbs is PermissionsActivity is getting launched

What did you expect to happen?

Our usecase is just to show push notifications from onesignal here is my setup. In MyApplication class oncreate() we just call OneSignalManager.init(this)

import android.content.Context
import android.text.TextUtils
import com.onesignal.OneSignal
import com.onesignal.debug.LogLevel
import com.onesignal.notifications.INotificationClickEvent
import com.onesignal.notifications.INotificationClickListener
import com.onesignal.notifications.INotificationLifecycleListener
import com.onesignal.notifications.INotificationWillDisplayEvent
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow

object OneSignalManager : INotificationLifecycleListener {
    private const val ONE_SIGNAL_APP_ID = "asdasdasd"

    private val _notificationReceivedFlow = MutableSharedFlow<Unit>(
        replay = 0,
        extraBufferCapacity = 1,
        onBufferOverflow = BufferOverflow.DROP_OLDEST
    )
    val notificationReceivedFlow: SharedFlow<Unit> = _notificationReceivedFlow.asSharedFlow()

    private val notificationClickListener: INotificationClickListener by lazy {
        object : INotificationClickListener {
            override fun onClick(event: INotificationClickEvent) {
                try {
                    OneSignalNotificationOpenedHandler(AppModule.context).notificationOpened(event)
                } catch (e: Exception) {
                    logException(LoggingTag.APP, e, "Failed to handle OneSignal notification click", true)
                }
            }
        }
    }

    fun init(context: Context) {
        try {

            OneSignal.initWithContext(context, ONE_SIGNAL_APP_ID)
            OneSignal.User.pushSubscription.optIn()

            OneSignal.Notifications.removeClickListener(notificationClickListener)
            OneSignal.Notifications.addClickListener(notificationClickListener)

            if (BuildConfig.DEBUG) {
                OneSignal.Debug.logLevel = LogLevel.VERBOSE
                OneSignal.User.addTag("is_test", "true")
            }

            registerPushTokenIfRequired("OneSignalManager:init")

            registerForegroundLifecycleListener(this)
        } catch (e: Exception) {
            logException(LoggingTag.APP, e, "Failed to initialize OneSignal", true)
        }
    }

    override fun onWillDisplay(event: INotificationWillDisplayEvent) {
        try {
            _notificationReceivedFlow.tryEmit(Unit)
        } catch (e: Exception) {
            logException(LoggingTag.APP, e, "Failed to emit notification received event", true)
        }
    }

    private fun registerForegroundLifecycleListener(listener: INotificationLifecycleListener) {
        try {
            OneSignal.Notifications.removeForegroundLifecycleListener(listener)
            OneSignal.Notifications.addForegroundLifecycleListener(listener)
        } catch (e: Exception) {
            logException(LoggingTag.APP, e, "Failed to register OneSignal foreground lifecycle listener", true)
        }
    }

    private fun unregisterForegroundLifecycleListener(listener: INotificationLifecycleListener) {
        try {
            OneSignal.Notifications.removeForegroundLifecycleListener(listener)
        } catch (e: Exception) {
            logException(LoggingTag.APP, e, "Failed to unregister OneSignal foreground lifecycle listener", true)
        }
    }

    fun cleanup() {
        try {
            OneSignal.Notifications.removeClickListener(notificationClickListener)
            unregisterForegroundLifecycleListener(this)
        } catch (e: Exception) {
            logException(LoggingTag.APP, e, "Failed to cleanup OneSignal listeners", true)
        }
    }

    fun registerPushTokenIfRequired(caller: String) {
        try {
            val registrationId = OneSignal.User.pushSubscription.token
            val oldRegistrationToken =
                SharedPreferencesWrapper.getInstance().getString(Constants.GCM_PUSH_TOKEN)
            if (TextUtils.equals(oldRegistrationToken, registrationId)) {
                return
            }
            SharedPreferencesWrapper.getInstance().putString(Constants.GCM_PUSH_TOKEN, registrationId)
            val userRegistration: IUserRegistration = UserRegistration(AppModule.context)
            userRegistration.registerUser(
                object : IUserRegisteredCallback {
                    override fun onRegistrationSuccess() {}

                    override fun onRegistrationFailure() {}
                },
            )
        } catch (e: Exception) {
            logException(LoggingTag.APP, e, "$caller:Failed to register OneSignal push token", true)
        }
    }
}

OneSignal Android SDK version

com.onesignal:OneSignal:5.4.0

Android version

15

Specific Android models

91% - Samsung
9% - Oppo

Relevant log output

Fatal Exception: java.lang.NullPointerException:
       at com.onesignal.core.internal.permissions.PermissionsViewModel.executeCallback(PermissionsViewModel.kt:153)
       at com.onesignal.core.internal.permissions.PermissionsViewModel.access$executeCallback(PermissionsViewModel.kt)
       at com.onesignal.core.internal.permissions.PermissionsViewModel$onRequestPermissionsResult$1.invokeSuspend(PermissionsViewModel.kt:141)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
       at kotlinx.coroutines.internal.DispatchedContinuation.resumeUndispatchedWith$kotlinx_coroutines_core(DispatchedContinuation.java:256)
       at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:178)
       at kotlinx.coroutines.CancellableContinuationImpl.takeState$kotlinx_coroutines_core(CancellableContinuationImpl.kt:168)
       at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:168)
       at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:474)
       at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:508)
       at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:497)
       at kotlinx.coroutines.CancellableContinuationImpl.resumeUndispatched(CancellableContinuationImpl.kt:595)
       at kotlinx.coroutines.android.HandlerContext$scheduleResumeAfterDelay$$inlined$Runnable$1.run(Runnable.kt:19)
       at android.os.Handler.handleCallback(Handler.java:959)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loopOnce(Looper.java:257)
       at android.os.Looper.loop(Looper.java:342)
       at android.app.ActivityThread.main(ActivityThread.java:9638)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929)

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions