基于算术表达式向FireBase写入数据的实现问题
问题描述
我的Firebase数据库结构如下:

系统原本会提示用户将金币兑换为经验值,但我希望通过FireBase记录实现用户验证——用户必须提交兑换请求才能完成操作。写入FireBase时需满足以下要求:
- 用户需指定要兑换的金币数量
- 兑换后从用户账户余额中扣除对应数量的金币
- 兑换的最低额度为5000金币
以下是我尝试实现写入FireBase的代码:
public void onClickResetCoin(View view) { mDatabase = FirebaseDatabase.getInstance().getReference("Resets"); mDatabase.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { users.child(userID).child("coins").setValue(rescoin); int coins = Integer.parseInt(edCoins.getText().toString()); int ResetCoin = rescoin - coins; String resetcoin = String.valueOf(ResetCoin); Reset newReset = new Reset(resetcoin); mDataBase.push().setValue(newReset); } @Override public void onCancelled(@NonNull DatabaseError error) { } }); }
解决方案
你的代码存在逻辑顺序错误、拼写问题以及缺少关键校验逻辑,下面给出修正后的完整实现:
1. 核心逻辑修正
- 替换持续监听的
addValueEventListener为一次性读取的addListenerForSingleValueEvent,避免不必要的重复触发 - 先校验用户输入合法性与兑换条件,再执行数据库操作
- 修正
mDataBase拼写错误为mDatabase - 调整逻辑顺序:先读取当前金币余额,再计算扣除后的值并更新
2. 完整修正代码
public void onClickResetCoin(View view) { // 获取并校验用户输入 String inputStr = edCoins.getText().toString().trim(); if (inputStr.isEmpty()) { // 提示用户输入有效数值 return; } int exchangeAmount; try { exchangeAmount = Integer.parseInt(inputStr); } catch (NumberFormatException e) { // 提示用户输入合法数字 return; } // 校验最低兑换额度 final int MIN_EXCHANGE = 5000; if (exchangeAmount < MIN_EXCHANGE) { // 提示用户最低需兑换5000金币 return; } // 读取用户当前金币余额并执行兑换逻辑 users.child(userID).child("coins").addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (!snapshot.exists()) { // 用户金币数据不存在,提示错误 return; } int currentCoins = snapshot.getValue(Integer.class); if (currentCoins < exchangeAmount) { // 用户金币不足,提示错误 return; } // 更新用户金币余额 users.child(userID).child("coins").setValue(currentCoins - exchangeAmount); // 记录兑换请求到Resets节点 DatabaseReference resetsRef = FirebaseDatabase.getInstance().getReference("Resets"); Reset newReset = new Reset(String.valueOf(exchangeAmount)); resetsRef.push().setValue(newReset); } @Override public void onCancelled(@NonNull DatabaseError error) { // 处理数据库错误,比如提示用户操作失败 } }); }
3. 并发安全优化建议
如果存在多端同时操作的场景,建议使用Firebase事务确保数据一致性,避免余额计算错误:
users.child(userID).child("coins").runTransaction(new Transaction.Handler() { @NonNull @Override public Transaction.Result doTransaction(@NonNull MutableData mutableData) { Integer currentCoins = mutableData.getValue(Integer.class); if (currentCoins == null || currentCoins < exchangeAmount) { return Transaction.abort(); } mutableData.setValue(currentCoins - exchangeAmount); return Transaction.success(mutableData); } @Override public void onComplete(@Nullable DatabaseError error, boolean committed, @Nullable DataSnapshot currentData) { if (committed && error == null) { // 兑换成功后记录请求 DatabaseReference resetsRef = FirebaseDatabase.getInstance().getReference("Resets"); Reset newReset = new Reset(String.valueOf(exchangeAmount)); resetsRef.push().setValue(newReset); } else { // 兑换失败,提示用户 } } });
内容的提问来源于stack exchange,提问作者ploxo
相关产品推荐
相关产品推荐

