React Native Firebase注册表单仅图片上传成功,用户数据未存实时数据库
解决React Native Firebase注册时用户数据无法存入实时数据库的问题
我来帮你排查下这个问题,结合你提供的代码来看,图片能成功上传说明Firebase的基本配置是没问题的,用户数据存不进去大概率是权限、异步逻辑或者参数配置的问题,咱们一步步来解决:
1. 优先检查Firebase实时数据库的规则权限
这是最常见的原因!默认情况下,Firebase实时数据库的规则是限制只有认证用户才能读写,但如果你的规则配置不对,或者测试模式过期了,就会导致写入失败。
你可以登录Firebase控制台,进入实时数据库 → 规则页面,检查当前规则是否允许认证用户写入:
{ "rules": { ".read": "auth != null", ".write": "auth != null" } }
如果是刚创建的数据库,可能默认是测试模式(.read和.write都设为true),但测试模式会在30天后自动关闭,这时候就会导致写入失败。你可以先临时改成测试模式测试是否是权限问题,但生产环境一定要改回基于认证的规则。
2. 修复currentUser异步获取的潜在问题
你在saveUserInfo里通过firebaseService.auth().currentUser.uid获取用户ID,但有时候注册成功后,currentUser可能还没完成更新,导致获取到null,进而写入失败。
更可靠的方式是在注册成功的回调里直接拿到用户凭证,把uid传递下去:
// 修改handleSignupOnPress方法 handleSignupOnPress = () => { const {image, email, password} = this.state; let validation = this.validateData(); console.warn(validation); if (validation == true) { this.toggleLoading(); firebaseService .auth() .createUserWithEmailAndPassword(email, password) .then((userCredential) => { // 直接从userCredential拿到当前用户的uid const uid = userCredential.user.uid; this.uploadImage(image, uid); }) .catch(error => { this.toggleLoading(); var errorCode = error.code; var errorMessage = error.message; alert(errorMessage); }); } };
然后修改uploadImage方法,接收uid并传递给saveUserInfo:
// 修改uploadImage方法,新增uid参数 uploadImage(uri, uid, mime = 'image/jpeg') { return new Promise((resolve, reject) => { const uploadUri = Platform.OS === 'ios' ? uri.replace('file://', '') : uri; let uploadBlob = ''; const imageRef = firebaseService .storage() .ref('images') .child(uuid.v4()); fs.readFile(uploadUri, 'base64') .then(data => { return Blob.build(data, {type: `${mime};BASE64`}); }) .then(blob => { uploadBlob = blob; return imageRef.put(blob, {contentType: mime}); }) .then(() => { uploadBlob.close(); return imageRef.getDownloadURL(); }) .then(url => { this.setState({ imageURI: url }, () => { alert('ImageURI => ', this.state.imageURI); this.saveUserInfo(uid); // 传递uid给saveUserInfo }); resolve(url); }) .catch(error => { this.toggleLoading(); reject(error); }); }); }
最后修改saveUserInfo方法,直接使用传递过来的uid:
// 修改saveUserInfo方法,接收uid参数 saveUserInfo = (uid) => { const {userName, email, imageURI} = this.state; const {navigate} = this.props.navigation; // 注意:不要把明文密码存到数据库里!Firebase Auth已经帮你管理密码了,存明文非常不安全 const params = { image: imageURI, username: userName, email: email, }; firebaseService .database() .ref('/Users') .child(uid) .set(params) .then(res => { this.toggleLoading(); navigate('Login'); }) .catch(err => { // 这里打印详细错误信息,方便排查 console.error('保存用户信息失败:', err); alert('保存用户信息失败:' + err.message); }); };
3. 其他排查要点
- 检查参数拼写:确认
state里的userName是否和表单输入绑定的字段一致,有没有拼写错误(比如写成username)。 - 检查数据库路径大小写:Firebase实时数据库的路径是大小写敏感的,如果你在控制台里创建的节点是
users(小写),而代码里用的是/Users(大写),就会导致写入到一个新的节点里,看起来像是没写入成功。 - 查看错误日志:在
saveUserInfo的catch里打印详细的错误信息,比如console.error(err),Firebase会返回具体的错误原因(比如权限不足、路径不存在等),这能帮你快速定位问题。
按照上面的步骤排查和修改,应该就能解决用户数据无法存入实时数据库的问题了!
内容的提问来源于stack exchange,提问作者Zaid Qureshi
相关产品推荐
相关产品推荐

