GetStream / stream-chat-android

:speech_balloon: Android Chat SDK ➜ Stream Chat API. UI component libraries for chat apps. Kotlin & Jetpack Compose messaging SDK for Android chat
https://getstream.io/chat/sdk/android/
Other
1.43k stars 268 forks source link

[V6] StreamOfflinePluginFactory was set at initialization, but the sdk required it #4717

Closed workspace closed 1 year ago

workspace commented 1 year ago

Describe the bug I am initializing ChatClient using jetpack app startup library. After completely shutting down the app, clicking the push notification to run the app, and then calling the state-related method(ex. watchChannelAsState), the following exception appears.

It could be a problem with our app's implementation, but we had no issues with v5.

FATAL EXCEPTION: main
Process: com.tntcrowd.educast, PID: 23369
java.lang.IllegalArgumentException: Offline plugin must be configured in ChatClient. You must provide StreamOfflinePluginFactory as a PluginFactory to be able to use LogicRegistry and StateRegistry from the SDK
    at io.getstream.chat.android.state.plugin.state.StateRegistry$Companion.get$stream_chat_android_state_release(StateRegistry.kt:200)
    at io.getstream.chat.android.state.extensions.ChatClientExtensions.getState(ChatClient.kt:66)
    at io.getstream.chat.android.state.extensions.internal.ChatClientKt.requestsAsState(ChatClient.kt:40)
    at io.getstream.chat.android.state.extensions.ChatClientExtensions$watchChannelAsState$1.invoke(ChatClient.kt:128)
    at io.getstream.chat.android.state.extensions.ChatClientExtensions$watchChannelAsState$1.invoke(ChatClient.kt:127)
    at io.getstream.chat.android.state.extensions.ChatClientExtensions$getStateOrNull$$inlined$map$2$2.emit(Emitters.kt:227)
    at kotlinx.coroutines.flow.DistinctFlowImpl$collect$2.emit(Distinct.kt:81)
    at io.getstream.chat.android.state.extensions.ChatClientExtensions$getStateOrNull$$inlined$map$1$2.emit(Emitters.kt:223)
    at kotlinx.coroutines.flow.StateFlowImpl.collect(StateFlow.kt:398)
    at kotlinx.coroutines.flow.StateFlowImpl$collect$1.invokeSuspend(Unknown Source:15)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at android.os.Handler.handleCallback(Handler.java:942)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at android.app.ActivityThread.main(ActivityThread.java:8747)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
    Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@11319a, Dispatchers.Main.immediate]

ChatClient initialization and connection was completed before calling watchChannelAsState

image

SDK version

To Reproduce (With our implementation)

  1. initialize ChatClient with Jetpack App Startup library.
  2. close app
  3. receive and click notification
  4. crash!

I'll try to reproduce with stream-chat-android sample

Expected behavior in v5, there was no problem.

Device:

leandroBorgesFerreira commented 1 year ago

Hello @workspace, could you share how you're initializing our SDK? I believe you didn't add the state plugin.

workspace commented 1 year ago

Hello @workspace, could you share how you're initializing our SDK? I believe you didn't add the state plugin.

StreamChatInitializer

class StreamChatInitializer : Initializer<Unit> {

    override fun create(context: Context) {
        // Set up the OfflinePlugin for offline storage
       val offlinePluginFactory = StreamOfflinePluginFactory(
            appContext = context
        )
        val statePluginFactory = StreamStatePluginFactory(
            config = StatePluginConfig(
                backgroundSyncEnabled = true,
                userPresence = true
            ),
            appContext = context
        )

        // Set up the client for API calls with the plugin for offline storage
        ChatClient.Builder("stream key", context)
            .logLevel(
                if (BuildConfig.DEBUG) {
                    ChatLogLevel.DEBUG
                } else {
                    ChatLogLevel.NOTHING
                }
            )
            .withPlugin(offlinePluginFactory, statePluginFactory )
            .build()
    }

    override fun dependencies(): List<Class<out Initializer<*>>> = emptyList()
}

AndroidManifest.xml

<manifest>
  <application>
    <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false"
            tools:node="merge">
            ...
            <meta-data
                android:name="com.holix.android.startup.StreamChatInitializer"
                android:value="androidx.startup" />
        </provider>
  </application>
</manifest>
image

This capture is a diff of a pull request that tested applying v6. If I open it by tapping the app icon, it works fine. However, there is a problem when opening the app through push notifications.

JcMinarro commented 1 year ago

Hi @workspace How are you connecting the user? Are you waiting for the result of the call?

If you are using connectUser(user, token).enqueue(), are you passing a callback for the result? Or are you ignoring the result and moving directly to the chat?

workspace commented 1 year ago

ignoring the result and moving directly to the chat.Then, I am watching initializationState before using ChatClient in the screen.

JcMinarro commented 1 year ago

Thanks for your reply. It helps me to understand the a little bit better the problem and find a bug we introduced with the new approach. It will be fixed soon

workspace commented 1 year ago

Thanks for the quick fix, I'm really happy to have contributed to stabilizing the STREAM V6 SDK. I can't wait to get the STREAM V6 SDK into my product. 😃

workspace commented 1 year ago

@JcMinarro I've verified that this snapshot build resolved the issue, I think we can close this issue.

Xshooter26 commented 5 months ago

@workspace @JcMinarro Thanks bro this helped me