androidandroid-jetpack-composedatastore

How use datastore for save token


I don't know how to call or use dataStore other than in the viewmodel

I want to use the token value from the data store, to save the value it works, but when I call the datastore to the MainRemote.kt file a problem occurs, I only know how to use it in the viewmodel

this code in my MainRemote.kt

class MainRemote() {
    var authDataStorePreferences = ConnectionReleaseApplication().authDataStorePreferences
    init {

    }

    val client = HttpClient(CIO) {
        defaultRequest {
            url(host = BuildConfig.apiDomain, port = 3000)
            contentType(ContentType.Application.Json)
        }

        install(Auth){
            bearer {
                loadTokens {
                    BearerTokens("token","mklklkl")
                }
            }
        }
        install(ContentNegotiation) {
            json(
                Json {
                    prettyPrint = true
                    isLenient = true
                    ignoreUnknownKeys = true

                }
            )
            install(Logging) {
                logger = Logger.ANDROID
                level = LogLevel.BODY
            }
        }


    }
}

this code when i register datastore in file ConnectionReleaseApp.kt

private const val AUTH_PREFERENCES_NAME = "auth_preferances_name"
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = AUTH_PREFERENCES_NAME)

class ConnectionReleaseApplication : Application() {
    lateinit var authDataStorePreferences: AuthDataStorePreferences

    override fun onCreate() {
        super.onCreate()
        authDataStorePreferences = AuthDataStorePreferences(dataStore)
    }
}

Error in my logcat

kotlin.UninitializedPropertyAccessException: lateinit property authDataStorePreferences has not been initialized
                                                                                                        at com.example.connectionmobile.ConnectionReleaseApplication.getAuthDataStorePreferences(ConnectionReleaseApplication.kt:14)
                                                                                                        at com.example.connectionmobile.api.remote.MainRemote.<init>(MainRemote.kt:22)
                                                                                                        at com.example.connectionmobile.api.repository.AuthRepository.login(AuthRepository.kt:12)
                                                                                                        at com.example.connectionmobile.viewModel.LoginViewModel.login(LoginViewModel.kt:55)
                                                                                                        at com.example.connectionmobile.ui.screen.LoginScreenKt$LoginScreen$1$4$1.invokeSuspend(LoginScreen.kt:77)
                                                                                                        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
                                                                                                        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
                                                                                                        at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
                                                                                                        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
                                                                                                        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:68)
                                                                                                        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1542)
                                                                                                        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1553)
                                                                                                        at android.view.Choreographer.doCallbacks(Choreographer.java:1109)
                                                                                                        at android.view.Choreographer.doFrame(Choreographer.java:984)
                                                                                                        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1527)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:958)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                        at android.os.Looper.loopOnce(Looper.java:257)
                                                                                                        at android.os.Looper.loop(Looper.java:368)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:8826)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:572)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1049)

enter image description here


Solution

  • You should always the Hilt to manage the dependency injection in the Android app. To make your DataStore instance available to any component or class you can write a hilt module:

    @InstallIn(SingletonComponent::class)
    @Module
    object DataStoreModule {
    
        @Binds
        @Singleton
        fun provideAuthPreference(
            dataStore: DataStore<Preferences>
        ): AuthDataStorePreferences = AuthDataStorePreferences(dataStore)
    
        @Provides
        @Singleton
        fun providePreferenceDataStore(@ApplicationContext context: Context): DataStore<Preferences> {
            return PreferenceDataStoreFactory.create {
                context.preferencesDataStoreFile("auth_preferances_name")
            }
        }
    }
    

    and then in your MainRemote class:

    class MainRemote() {
        @Inject
        lateint var authDataStorePreferences: AuthDataStorePreferences
        
        //rest of the code 
    }