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

如何在Android Studio中对Firebase实时数据库两节点做算术运算

Firebase实时数据库金额更新:应付款扣除已付款实现

需求说明

Firebase实时数据库包含Customers和Transaction两个节点,Transaction以Customer节点中的**车牌号(vehicleNumber)**作为节点键进行关联。需要实现逻辑:将指定客户的应付款金额减去对应交易记录中的已付款金额,并更新回数据库。

数据库节点结构

Customers节点数据

"Customers": {
    "-NFFTcWFGLXi063jCTcT": {
      "branch": "Rajeev Nagar",
      "currentDownPayment": "80000",
      "currentdueAmount": "20000.0",
      "customerAadharNumber": "123456",
      "customerAddress": "ANYWHERE",
      "customerName": "VIKASH",
      "customerPhoneNumber": "7481900892",
      "customerTenure": "12",
      "dateOfdelevry": "28/10/2022",
      "downPayment": "100000",
      "duePayment": "100000.0",
      "emiPerMonth": "8333",
      "emiStartDate": "26/10/2022",
      "granterName": "RATHI",
      "granterPhoneNumber": "7481900896",
      "localitymodal": "NEAR ME",
      "motorNumber": "QWERT",
      "outStandingAmount": "120000.0",
      "vehicleAmount": "200000",
      "vehicleBodyType": "Steel",
      "vehicleColour": "Gray",
      "vehicleNumber": "1234567890QWERTYU"
    }
}

Transaction节点数据

"Transaction": {
    "1234567890QWERTYU": {
      "-NFFZLr7-9sTrZ1OlbjF": {
        "dateOfPayment": "27/10/2022",
        "discountGiven": "00",
        "discountRemarks": "8000",
        "lateFine": "no discount ",
        "paymentReceived": "500"
      }
    }
}

现有代码片段

databasePaymentUpdate = FirebaseDatabase.getInstance().getReference("Customers");

databasePaymentUpdate.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        if (snapshot.exists()) {
            for (DataSnapshot ds : snapshot.getChildren()) {
                String VehicleNumber = ds.child("vehicleNumber").getValue(String.class);
                String vehNo = PaymentUpdateVehicleNumber.getText().toString().trim();
                if (VehicleNumber.equals(vehNo)) {
                    Toast.makeText(PaymentUpdate.this, "Welcome to Jyoti Motors", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {
        // 处理数据库读取失败情况
        Toast.makeText(PaymentUpdate.this, "数据库读取失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

完整实现方案

在现有代码基础上,补充金额计算与更新逻辑:

databasePaymentUpdate = FirebaseDatabase.getInstance().getReference("Customers");
DatabaseReference transactionRef = FirebaseDatabase.getInstance().getReference("Transaction");

databasePaymentUpdate.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        if (snapshot.exists()) {
            String vehNo = PaymentUpdateVehicleNumber.getText().toString().trim();
            for (DataSnapshot ds : snapshot.getChildren()) {
                String vehicleNumber = ds.child("vehicleNumber").getValue(String.class);
                if (vehicleNumber != null && vehicleNumber.equals(vehNo)) {
                    // 1. 获取客户当前应付款金额(这里以currentdueAmount为例,可按需替换为duePayment或outStandingAmount)
                    String currentDueStr = ds.child("currentdueAmount").getValue(String.class);
                    if (currentDueStr == null) {
                        Toast.makeText(PaymentUpdate.this, "未找到应付款数据", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    double currentDue;
                    try {
                        currentDue = Double.parseDouble(currentDueStr);
                    } catch (NumberFormatException e) {
                        Toast.makeText(PaymentUpdate.this, "应付款格式错误", Toast.LENGTH_SHORT).show();
                        return;
                    }

                    // 2. 读取该车牌号对应的所有交易记录,累加已付款金额
                    transactionRef.child(vehNo).addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot transactionSnapshot) {
                            double totalPaid = 0.0;
                            for (DataSnapshot transactionDs : transactionSnapshot.getChildren()) {
                                String paymentReceivedStr = transactionDs.child("paymentReceived").getValue(String.class);
                                if (paymentReceivedStr != null) {
                                    try {
                                        totalPaid += Double.parseDouble(paymentReceivedStr);
                                    } catch (NumberFormatException e) {
                                        // 跳过格式错误的交易记录
                                        continue;
                                    }
                                }
                            }

                            // 3. 计算更新后的应付款金额
                            double updatedDue = currentDue - totalPaid;

                            // 4. 更新回Customer节点的对应字段
                            ds.getRef().child("currentdueAmount").setValue(String.valueOf(updatedDue))
                                    .addOnSuccessListener(aVoid -> {
                                        Toast.makeText(PaymentUpdate.this, "金额更新成功", Toast.LENGTH_SHORT).show();
                                    })
                                    .addOnFailureListener(e -> {
                                        Toast.makeText(PaymentUpdate.this, "金额更新失败:" + e.getMessage(), Toast.LENGTH_SHORT).show();
                                    });
                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError error) {
                            Toast.makeText(PaymentUpdate.this, "交易记录读取失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    });
                    break; // 找到目标客户后跳出循环
                }
            }
        } else {
            Toast.makeText(PaymentUpdate.this, "未找到客户数据", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {
        Toast.makeText(PaymentUpdate.this, "客户数据读取失败:" + error.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

注意事项

  • 数据类型安全:数据库中金额以字符串存储,需添加异常捕获处理格式转换错误,避免崩溃。
  • 并发更新防护:如果存在多端同时修改同一客户金额的场景,建议使用Firebase事务更新(runTransaction)替代直接setValue,防止数据不一致。
  • 权限配置:确保Firebase数据库规则允许对Customers和Transaction节点进行读写操作。

内容的提问来源于stack exchange,提问作者Vivek Kumar pandey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:45:37