You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Room数据库用户登录验证问题:输入与库中数据不匹配如何解决?

问题描述

我尝试通过Room数据库中的邮箱(email)和密码(password)实现用户登录功能,但发现输入的信息并未与库中数据进行有效比对,请问该如何实现二者的比对?

现有代码

DAO层查询语句

@Query("SELECT * FROM user_table WHERE email Like :email AND password Like :password")
fun loginUser(email: String?, password: String?): User?

仓库层调用代码

suspend fun loginUser(email: String?, password: String?)=groovyDataBase.userDao().loginUser(email, password)

ViewModel层代码

fun loginUser(email:String, password:String){
    viewModelScope.launch(Dispatchers.IO) {
        groovyRepo.loginUser(email, password)
    }
}

登录按钮点击事件代码

if (email.isNotEmpty()&& password.isNotEmpty()){
    mUserViewModel.loginUser(email,password)
    Toast.makeText(
        context,
        "Successfully Login",
        Toast.LENGTH_LONG
    ).show()
    //navigate back to Home
    navController.navigate("HomeScreen")
}
else {
    Toast.makeText(
        context,
        "Please Enter valid email & password",
        Toast.LENGTH_LONG
    ).show()
}
问题分析与解决步骤

你的代码存在三个核心问题,导致登录校验失效:

  1. DAO使用Like进行模糊匹配,而非精确匹配
  2. ViewModel未将查询结果反馈给UI层
  3. UI层未等待查询结果,直接执行登录成功逻辑

以下是修正方案:

1. 修正DAO查询语句

登录需要精确匹配邮箱和密码,把Like替换为=:

@Query("SELECT * FROM user_table WHERE email = :email AND password = :password")
fun loginUser(email: String?, password: String?): User?

2. 改造ViewModel传递登录状态

使用LiveData将查询结果传递给UI层:

// 定义内部可变LiveData,对外暴露不可变版本
private val _loginResult = MutableLiveData<Boolean>()
val loginResult: LiveData<Boolean> = _loginResult

fun loginUser(email: String, password: String){
    viewModelScope.launch(Dispatchers.IO) {
        // 调用仓库查询用户
        val matchedUser = groovyRepo.loginUser(email, password)
        // 通过postValue更新UI线程的状态
        _loginResult.postValue(matchedUser != null)
    }
}

3. 修改UI层逻辑,等待校验结果

在Activity/Fragment中观察ViewModel的loginResult,根据结果处理后续操作:

// 在页面初始化时添加观察(比如onViewCreated或onCreate)
mUserViewModel.loginResult.observe(viewLifecycleOwner) { isLoginSuccess ->
    if (isLoginSuccess) {
        Toast.makeText(context, "登录成功", Toast.LENGTH_LONG).show()
        navController.navigate("HomeScreen")
    } else {
        Toast.makeText(context, "邮箱或密码错误", Toast.LENGTH_LONG).show()
    }
}

// 登录按钮点击事件简化为:
if (email.isNotEmpty() && password.isNotEmpty()) {
    mUserViewModel.loginUser(email, password)
} else {
    Toast.makeText(context, "请输入有效的邮箱和密码", Toast.LENGTH_LONG).show()
}

补充说明

  • Like用于模糊搜索场景(比如搜索包含某关键词的邮箱),登录必须用精确匹配,否则会出现输入相似内容也能登录的安全问题
  • 必须等待Room的异步查询完成后再判断登录状态,之前的代码跳过了校验步骤直接跳转,自然无法实现有效比对
  • 使用LiveData/StateFlow是Jetpack架构中ViewModel与UI通信的标准方式,确保状态更新能安全通知到UI线程

内容的提问来源于stack exchange,提问作者Noor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 16:41:32