Kotlin开发中如何将带@和.com的邮箱正确存储到Firebase?
问题根因
- Firebase Realtime Database 的节点 Key 不允许包含
.、#、$、[、]等特殊字符,你直接把带.后缀的邮箱地址作为节点 Key 存储,本身就会触发格式异常。 - 邮箱编解码逻辑完全写反:你现有
decodeUserEmail方法是把逗号替换成点,但实际正确逻辑是存储时把邮箱中的点替换为逗号作为节点Key,读取时再把逗号替换回点,反向操作自然匹配不到数据。 - 查询返回结构处理错误:调用
orderByChild()查询后返回的dataSnapshot是符合条件的子节点集合,不能直接用邮箱作为Key调用child()取值,需要先取集合中的第一个子节点再操作。 - 字段名大小写不匹配:你的User数据类中密码字段名为
PasswordRegister,但你查询时写的是passwordRegister,首字母大小写不一致,无法匹配到字段会返回null,调用equals时直接触发空指针崩溃。
修复方案
1. 新增统一的邮箱编解码工具方法
// 存储前编码邮箱,替换点为逗号,适配Firebase节点Key规则 fun encodeEmailForFirebaseKey(email: String) = email.replace(".", ",") // 读取后解码邮箱,替换逗号恢复为原始点格式 fun decodeEmailFromFirebaseKey(encodedEmail: String) = encodedEmail.replace(",", ".")
2. 修正用户信息存储逻辑
val FullName = FullName.getText().toString() val PhoneNo = PhoneNo.getText().toString().toInt() val Age = Age.getText().toString().toInt() val EmailAddress = EmailAddress.getText().toString() val BankAccNo = BankAccNo.getText().toString() val PasswordRegister = PasswordRegister.getText().toString() val User = User(FullName,PhoneNo,Age,EmailAddress, BankAccNo,PasswordRegister) // 用编码后的邮箱作为节点Key,避免特殊字符问题 val encodedEmail = encodeEmailForFirebaseKey(EmailAddress) myRef.child(encodedEmail).setValue(User)
3. 修正身份校验逻辑
private fun isUser() { val userEnteredEmail = email.getText().toString().trim() val userEnteredPassword = password1.getText().toString().trim() val reference = FirebaseDatabase.getInstance().getReference("User") // 直接用原始邮箱匹配emailAddress字段,不需要提前编码 val checkUser: Query = reference.orderByChild("emailAddress").equalTo(userEnteredEmail) checkUser.addListenerForSingleValueEvent(object : ValueEventListener { override fun onDataChange(@NonNull dataSnapshot: DataSnapshot) { if (dataSnapshot.exists()) { // 取第一个匹配的用户节点 val userSnapshot = dataSnapshot.children.first() // 字段名要和数据类定义完全一致,首字母大写,增加空安全判断 val passwordFromDB = userSnapshot.child("PasswordRegister").getValue(String::class.java) if (passwordFromDB == userEnteredPassword) { val intent = Intent(baseContext, Home::class.java) intent.putExtra("EXTRA_SESSION_ID", userEnteredEmail) startActivity(intent) } } } override fun onCancelled(@NonNull databaseError: DatabaseError) {} }) }
内容的提问来源于stack exchange,提问作者ABI
相关产品推荐
相关产品推荐

