currently, I am working on a project where I try to use both dagger (hilt) and parseServer SDK. The problem is that in my opinion it is impossible to use this combination in one project...
Here is my opinion on why I think it is impossible, at least in the way and knows how I would like it to be:
When using Parse SDK and creating a class, you have to annotate it with @ParseClasssName("YourDBClassName")
. This custom class has to be registered in onCreate()
with ParseObject.registerSubclass(YourClassName::class.java)
before calling Parse.initialize...
.
Now comes my problem: When using dagger (hilt) and creating this customClass, it has to be injected with @Inject lateinit var YourClassName
before calling onCreate()
. But when you inject
this customClass before calling the onCreate()
parse throws an Error, because 1. It does not know that this class is a customClass and 2. the ParseObject has to be created within the onCreate()
method.
To make it a bit more clear, here is my code and what I want to achieve:
@ParseClassName("User")
data class User(var name: String, var passWord: String, var eMail: String) : ParseUser() {
@Inject constructor(): this("","","")
// Creates a new User
fun signUpWithOutVerification() = apply {
username = name
setPassword(passWord)
email = eMail
signUpInBackground()
}
// logIn
fun logIn() = logInInBackground(name, passWord) ?: Timber.e("logIn Error")
// logOut
fun logOut() = logOutInBackground() ?: Timber.e("logOut Error")
// Update
fun updateCredential(key: String, value: Any) = getCurrentUser().apply {
put(key, value)
saveInBackground()
} ?: Timber.e("Update failed")
// Delet and Logout
fun deleteUser() = getCurrentUser().apply {
deleteInBackground()
logOut()
} ?: Timber.e("Delete failed")
@Module
@InstallIn(ApplicationComponent::class)
object ApplicationModule {
@Provides
@Singleton
fun provideUser() = User()
}
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var user: User
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ParseObject.registerSubclass(User::class.java)
Parse.initialize(
Parse.Configuration.Builder(this)
.applicationId("YourAppKey")
.clientKey("YourClientKey")
.server("https://parseapi.back4app.com")
.build()
)
Timber.plant(Timber.DebugTree())
lateinit var userName: String
lateinit var userPw: String
btn_signup.setOnClickListener {
userName = etName.text.toString()
userPw = etPassword.text.toString()
user.apply{
name = userName
passWord = userPw
eMail = "$userName@email.com"
signUpWithOutVerification()
}
}
@HiltAndroidApp
class App : Application()
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.app, PID: 31532
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app/com.example.app.ui.view.MainActivity}: java.lang.IllegalArgumentException: You must create this type of ParseObject using ParseObject.create() or the proper subclass.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.IllegalArgumentException: You must create this type of ParseObject using ParseObject.create() or the proper subclass.
at com.parse.ParseObject.<init>(ParseObject.java:162)
at com.parse.ParseObject.<init>(ParseObject.java:132)
at com.parse.ParseUser.<init>(ParseUser.java:56)
at com.example.app.data.model.User.<init>(User.kt:10)
at com.example.app.data.model.User.<init>(User.kt:12)
at com.example.app.di.modules.ApplicationModule.provideUser(ApplicationModule.kt:16)
at com.example.app.di.modules.ApplicationModule_ProvideUserFactory.provideUser(ApplicationModule_ProvideUserFactory.java:27)
at com.example.app.DaggerApp_HiltComponents_ApplicationC.getUser(DaggerApp_HiltComponents_ApplicationC.java:61)
at com.example.app.DaggerApp_HiltComponents_ApplicationC.access$1000(DaggerApp_HiltComponents_ApplicationC.java:41)
at com.example.app.DaggerApp_HiltComponents_ApplicationC$ActivityRetainedCImpl$ActivityCImpl.injectMainActivity2(DaggerApp_HiltComponents_ApplicationC.java:174)
at com.example.app.DaggerApp_HiltComponents_ApplicationC$ActivityRetainedCImpl$ActivityCImpl.injectMainActivity(DaggerApp_HiltComponents_ApplicationC.java:155)
at com.example.app.ui.view.Hilt_MainActivity.inject(Hilt_MainActivity.java:62)
at com.example.app.ui.view.Hilt_MainActivity.onCreate(Hilt_MainActivity.java:37)
at com.example.app.ui.view.MainActivity.onCreate(MainActivity.kt:22)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
So it IS POSSIBLE that I just don't have the knowledge to write the code I want. What I want to do is, that dagger (hilt) creates the User + gets his Name etc...
I appreciate every help, thank you!
You should move the registerSubclass()
code to your application
class.
Your application
class:
@HiltAndroidApp
class App : Application() {
override fun onCreate() {
super.onCreate()
ParseObject.registerSubclass(User::class.java)
Parse.initialize(
Parse.Configuration.Builder(this)
.applicationId("YourAppKey")
.clientKey("YourClientKey")
.server("https://parseapi.back4app.com")
.build()
)
}
}
In Manifest file:-
<application
android:name=".App"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
....