I have a shop app , if we beginning from the start user is need to sign up (if this account already in database he need to login). I have room data base with dao, database classes.
In sing up fragment i have 2 edittext fields with hint email and password .
I already have fun that is checking fields for empty.
I have already done initialiazation for database class in my fragment.
When user is clicking a button sign up (in the sign up fragment) his data will save in room db and user will go next to the next fragment.
I have error in my DAO class I guess
The code is below.
UserModel
@Entity(tableName = "user_table")
data class UserModel(
@PrimaryKey(autoGenerate = true)
val id: Int?,
@ColumnInfo
val email: String? = "",
@ColumnInfo
val password:String? = ""
)
FragmentForActivityMain
class FragmentForActivityMain : Fragment(R.layout.fragment_for_activity_main) {
private lateinit var binding :FragmentForActivityMainBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentForActivityMainBinding.inflate(inflater,container,false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init(){
val viewModel = ViewModelProvider(this).get(fragmentmainviewmodel::class.java)
viewModel.initdb()
binding.buttontogologin.setOnClickListener {
findNavController().navigate(R.id.action_fragmentForActivityMain_to_loginFragment)
}
binding.signupbutton.setOnClickListener {
findNavController().navigate(R.id.action_fragmentForActivityMain_to_signUpFragment)
}
}
}
Const File
import UserRepository.UserRepository
lateinit var repository:UserRepository
Class fragmentmainviewmodel
import Const.repository
import Room.Database.UserDB
import UserRepository.RepositoryAndDaoRealization
import android.app.Application
import androidx.lifecycle.AndroidViewModel
class fragmentmainviewmodel(application: Application):AndroidViewModel(application) {
val context = application
fun initdb(){
val daouser = UserDB.getadminDB(context).getDAO()
repository = RepositoryAndDaoRealization(daouser)
}
}
DAO class
@Dao
interface UserDAO {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertnewUser(user:UserModel)
@Query("select * from USER_TABLE where email like email and password like password")
suspend fun validationforuser(userModel: UserModel)
@Query("select * from user_table")
fun getAllUser():LiveData<List<UserModel>>
Database
@Database (entities = [UserModel::class], version = 5, exportSchema = true)
abstract class UserDB:RoomDatabase(){
abstract fun getDAO(): UserDAO
companion object{
private var database : UserDB?= null
@Synchronized
fun getadminDB(context: Context):UserDB{
return if(database == null){
database= Room.databaseBuilder(context,UserDB::class.java,"UserDatabase").build()
database as UserDB
}else{
database as UserDB
}
}
}
}
SignUpFragment
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import com.example.myapplication.Model.UserModel
import com.example.myapplication.R
import com.example.myapplication.databinding.FragmentSignUpBinding
class SignUpFragment : Fragment() {
lateinit var binding:FragmentSignUpBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentSignUpBinding.inflate(inflater)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
}
private fun init(){
val viewModel = ViewModelProvider(this).get(SingUpViewModel::class.java)
binding.signupbuttoninsignupfragment.setOnClickListener {
val espace = binding.EmailSpaceSignUp.text.toString()
val pspace = binding.PasswordSpaceSignUp.text.toString()
viewModel.insert(UserModel(email = espace, password = pspace, id = id )){}
findNavController().navigate(R.id.action_signUpFragment_to_lastfragment)
if(binding.EmailSpaceSignUp == null){
Toast.makeText(context,"Email space is empty , you need to write some data there",Toast.LENGTH_SHORT).show()
}
if(binding.PasswordSpaceSignUp == null){
Toast.makeText(context,"Password space is empty , you need to write some data there",Toast.LENGTH_SHORT).show()
}
if(binding.PasswordSpaceSignUp.length()<8){
Toast.makeText(context,"Password is too short",Toast.LENGTH_SHORT).show()
}
if(binding.EmailSpaceSignUp.length()<18){
Toast.makeText(context,"Email is too short",Toast.LENGTH_SHORT).show()
}
}
}
}
SingUpViewModel
class SingUpViewModel: ViewModel() {
fun insert(userModel: UserModel,onSuccess:()->Unit) =
viewModelScope.launch(Dispatchers.IO) {
repository.insertUser(userModel){
onSuccess()
}
}
}
Class RepositoryAndDaoRealization
class RepositoryAndDaoRealization(private var dao:UserDAO):UserRepository {
override val allusers: LiveData<List<UserModel>>
get() = dao.getAllUser()
override suspend fun insertUser(userModel: UserModel, onSuccess: () -> Unit) {
dao.insertnewUser(userModel)
onSuccess()
}
override suspend fun validateuser(userModel: UserModel, onSuccess: () -> Unit) {
dao.validationforuser(userModel)
onSuccess()
}
}
UserRepository
interface UserRepository {
val allusers:LiveData<List<UserModel>>
suspend fun insertUser(userModel: UserModel,onSuccess:()->Unit)
suspend fun validateuser(userModel: UserModel,onSuccess: () -> Unit)
}
CodePudding user response:
Your issues are with:-
@Query("select * from USER_TABLE where email like email and password like password")
suspend fun validationforuser(userModel: UserModel)
Room cannot ascertain what to do with the output from the query.
So you need to have something like:-
suspend fun validationforuser(userModel: UserModel): List<UserModel>
So Room knows what you want to do with the output from the query.
However, Room will then complain about the parameter passed to the function as per:-
error: Query method parameters should either be a type that can be converted into a database column or a List / Array that contains such type. You can consider adding a Type Adapter for this.
You could instead use:-
@Query("select * from USER_TABLE where email like email and password like password")
suspend fun validationforuser(email: String, password: String): List<UserModel>
BUT then Room will complain as it doesn't know what to do with the email and password parameters as they are not coded within the query. As per:-
error: Unused parameters: email,password
So you could then use:-
@Query("select * from USER_TABLE where email like :email and password like :password")
suspend fun validationforuser(email: String, password: String): List<UserModel>
Noting that instead of passing a UserModel, that you should pass the email and password from the UserModel.
e.g.
dao.validationforuser(userModel.email,userModel.password)