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

[Bug]: Crashes when OneSignal is used immediately after initiWithContext called #2192

Open
1 task done
fanwgwg opened this issue Sep 14, 2024 · 4 comments
Open
1 task done

Comments

@fanwgwg
Copy link

fanwgwg commented Sep 14, 2024

What happened?

In my code, I've consistently encountered crashes when using OneSignal APIs after calling OneSignal.initWithContext, specifically receiving the error: java.lang.Exception: Must call 'initWithContext' before use.

I believe this is related to the recent changes in PR #2151, which moved initialization to a background thread. However, there seems to be no clear guidance from OneSignal on how to determine when the SDK has completed initialization and when it's safe to call other APIs.

Relying on developers to wait for an arbitrary period, such as 2 seconds, before invoking OneSignal APIs is not a viable or professional coding practice—this is not something we see in other SDKs. If the initialization is now asynchronous, then the rest of the APIs should also be asynchronous. For instance, APIs could return a result only after initialization has completed.

Overall, I feel the quality of the SDK urgently needs improvement, especially given the frequent crashes introduced since the 5.0 release. Addressing these issues with more robust handling of the initialization process is crucial.

Steps to reproduce?

OneSignal.initWithContext(xxx);
OneSignal.getUser();

What did you expect to happen?

The code should not crash

OneSignal Android SDK version

com.onesignal:OneSignal:5.1.21

Android version

14

Specific Android models

No response

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct
@fanwgwg fanwgwg changed the title [Bug]: Unable to use OneSignal after initiWithContext [Bug]: Crashes when OneSignal is used immediately after initiWithContext called Sep 14, 2024
@jinliu9508
Copy link
Contributor

Hello @fanwgwg, thank you for the report. Could you share more of the stack trace regarding the crash? I have tested your code but was unable to reproduce the exception. Part of the initialization has been moved to the background; however, you can still successfully call methods like getUser() immediately after initWithContext(). The system allows components like User to be initialized even if the background initialization is not yet complete. In this case, the system will simply use the component that was initialized by your call.

I do notice that this error can occur in certain multi-threading environments that are not specifically covered in our documentation. If you could provide more details, including how you are calling OneSignal API methods and the stack trace when the crash occurs, I can assist in identifying the root cause of the issue.

@fanwgwg
Copy link
Author

fanwgwg commented Sep 25, 2024

Here's the stacktrace:

 Caused by java.lang.Exception: Must call 'initWithContext' before use
       at com.onesignal.internal.OneSignalImp.getUser(OneSignalImp.kt:123)
       at com.onesignal.OneSignal.getUser(OneSignal.kt:46)
       at com.xxxxx.appsettings.AppSettingsViewModel.refreshNotificationStatus(AppSettingsViewModel.java:82)
       at com.xxxxx.appsettings.AppSettingsViewModel.init(AppSettingsViewModel.java:191)
       at com.xxxxx.appsettings.AppSettingsViewModel.<init>(AppSettingsViewModel.java:61)
       at com.xxxxx.appsettings.AppSettingsViewModel_Factory.newInstance(AppSettingsViewModel_Factory.java:83)
       at com.xxxxx.DaggerNoteApplication_HiltComponents_SingletonC$ViewModelCImpl$SwitchingProvider.get(DaggerNoteApplication_HiltComponents_SingletonC.java:3154)
       at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory$2.createViewModel(HiltViewModelFactory.java:132)
       at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory$2.create(HiltViewModelFactory.java:103)
       at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create(HiltViewModelFactory.java:170)
       at androidx.lifecycle.ViewModelProvider$Factory.create(ViewModelProvider.android.kt:158)
       at androidx.lifecycle.viewmodel.ViewModelProviderImpl_androidKt.createViewModel(ViewModelProviderImpl_android.kt:34)
       at androidx.lifecycle.viewmodel.ViewModelProviderImpl.getViewModel$lifecycle_viewmodel_release(ViewModelProviderImpl.java:65)
       at androidx.lifecycle.viewmodel.ViewModelProviderImpl.getViewModel$lifecycle_viewmodel_release$default(ViewModelProviderImpl.java:47)
       at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:91)
       at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:109)

The code setup is that:
AppSettingsActivity

@AndroidEntryPoint
public class AppSettingsActivity extends AppCompatActivity {

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    OneSignal.initWithContext(context, CredentialUtils.getOneSignalId());
    AppSettingsViewModel appSettingsViewModel =
        new ViewModelProvider(this).get(AppSettingsViewModel.class);
   }
}

AppSettingsViewModel

  @Inject
  AppSettingsViewModel() {
     init()
  }

  private void init() {
     refreshNotificationStatus();
  }

  private void refreshNotificationStatus() {
     boolean isOptIn = OneSignal.getUser().getPushSubscription().getOptedIn();
  }

@jinliu9508
Copy link
Contributor

@fanwgwg Are you still able to reproduce the exception if you call 'OneSignal.getUser().getPushSubscription().getOptedIn();' immediately after 'OneSignal.initWithContext()'? It seems that your ViewModelProvider might be initialized earlier than AppSettingsActivity.onCreate(), depending on how your injection works.

Does this exception occur every time, most of the time, or only occasionally when you run the app?

@fanwgwg
Copy link
Author

fanwgwg commented Sep 26, 2024

I'm not able to reproduce it, I'm only seeing it from Crashlytics. Based on the stacktrace, I do believe that AppSettingsActivity.onCreate() is already called before OneSignal.getUser() is called.

Sharing the complete stacktrace here as I only pasted the ones related to the viewmodel in my previous reply. This is the exact stacktrace on Crashlytics, except that I've removed our package id.

You'll a line of com.xxxxx.appsettings.AppSettingsActivity.onCreate (AppSettingsActivity.java) inside the stacktrace.

com.onesignal.internal.OneSignalImp.getUser (OneSignalImp.kt:123)
com.onesignal.OneSignal.getUser (OneSignal.kt:46)
com.xxxxx.appsettings.AppSettingsViewModel.refreshNotificationStatus (AppSettingsViewModel.java:82)
com.xxxxx.appsettings.AppSettingsViewModel.init (AppSettingsViewModel.java:191)
com.xxxxx.appsettings.AppSettingsViewModel.<init> (AppSettingsViewModel.java:61)
com.xxxxx.appsettings.AppSettingsViewModel_Factory.newInstance (AppSettingsViewModel_Factory.java:83)
com.xxxxx.DaggerNoteApplication_HiltComponents_SingletonC$ViewModelCImpl$SwitchingProvider.get (DaggerNoteApplication_HiltComponents_SingletonC.java:3154)
dagger.hilt.android.internal.lifecycle.HiltViewModelFactory$2.createViewModel (HiltViewModelFactory.java:132)
dagger.hilt.android.internal.lifecycle.HiltViewModelFactory$2.create (HiltViewModelFactory.java:103)
dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.create (HiltViewModelFactory.java:170)
androidx.lifecycle.ViewModelProvider$Factory.create (ViewModelProvider.android.kt:158)
androidx.lifecycle.viewmodel.ViewModelProviderImpl_androidKt.createViewModel (ViewModelProviderImpl_android.kt:34)
androidx.lifecycle.viewmodel.ViewModelProviderImpl.getViewModel$lifecycle_viewmodel_release (ViewModelProviderImpl.java:65)
androidx.lifecycle.viewmodel.ViewModelProviderImpl.getViewModel$lifecycle_viewmodel_release$default (ViewModelProviderImpl.java:47)
androidx.lifecycle.ViewModelProvider.get (ViewModelProvider.java:91)
androidx.lifecycle.ViewModelProvider.get (ViewModelProvider.java:109)
com.xxxxx.appsettings.AppSettingsFragment.onCreate (AppSettingsFragment.java:58)
androidx.fragment.app.Fragment.performCreate (Fragment.java:3099)
androidx.fragment.app.FragmentStateManager.create (FragmentStateManager.java:524)
androidx.fragment.app.FragmentStateManager.moveToExpectedState (FragmentStateManager.java:282)
androidx.fragment.app.FragmentStore.moveToExpectedState (FragmentStore.java:114)
androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1675)
androidx.fragment.app.FragmentManager.dispatchStateChange (FragmentManager.java:3269)
androidx.fragment.app.FragmentManager.dispatchCreate (FragmentManager.java:3176)
androidx.fragment.app.Fragment.restoreChildFragmentState (Fragment.java:1994)
androidx.fragment.app.Fragment.onCreate (Fragment.java:1972)
androidx.navigation.fragment.NavHostFragment.onCreate (NavHostFragment.kt:163)
androidx.fragment.app.Fragment.performCreate (Fragment.java:3099)
androidx.fragment.app.FragmentStateManager.create (FragmentStateManager.java:524)
androidx.fragment.app.FragmentStateManager.moveToExpectedState (FragmentStateManager.java:282)
androidx.fragment.app.FragmentStore.moveToExpectedState (FragmentStore.java:114)
androidx.fragment.app.FragmentManager.moveToState (FragmentManager.java:1675)
androidx.fragment.app.FragmentManager.dispatchStateChange (FragmentManager.java:3269)
androidx.fragment.app.FragmentManager.dispatchCreate (FragmentManager.java:3176)
androidx.fragment.app.FragmentController.dispatchCreate (FragmentController.java:252)
androidx.fragment.app.FragmentActivity.onCreate (FragmentActivity.java:219)
com.xxxxx.appsettings.Hilt_AppSettingsActivity.onCreate (Hilt_AppSettingsActivity.java)
com.xxxxx.appsettings.AppSettingsActivity.onCreate (AppSettingsActivity.java)
android.app.Activity.performCreate (Activity.java:8657)
android.app.Activity.performCreate (Activity.java:8636)
android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1417)
android.app.ActivityThread.performLaunchActivity (ActivityThread.java:4165)
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:4340)
android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:101)
android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:135)
android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:95)
android.app.ActivityThread$H.handleMessage (ActivityThread.java:2584)
android.os.Handler.dispatchMessage (Handler.java:106)
android.os.Looper.loopOnce (Looper.java:226)
android.os.Looper.loop (Looper.java:313)
android.app.ActivityThread.main (ActivityThread.java:8810)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:604)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants