【问题标题】:Run as a transaction in Realtime Database [duplicate]在实时数据库中作为事务运行 [重复]
【发布时间】:2021-05-13 17:51:56
【问题描述】:

我正在尝试在 Android 上制作应用程序,我是初学者。

我尝试增加产品的“库存”,但我的以下代码不可靠。我在设备上遇到了连接问题,并且“库存”没有正确增加。如何以transaction 的形式执行它?我找不到大量文档。

final HashMap<String, BigDecimal> detalle = new HashMap<String, BigDecimal>();

Query query = mDatabase.child("COMPRAS").child(key).child("COMPRASPRODUCTO");
query.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()){
            CompraProducto producto = ds.getValue(CompraProducto.class);
            detalle.put(producto.getId(),new BigDecimal(producto.getCantidad()));
        }
        for (String key : detalle.keySet()) {
                Query queryp = mDatabase.child("PRODUCTO").child(key);
                queryp.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot data) {
                        Producto p = data.getValue(Producto.class);
                        try{
                            stockOriginal = new BigDecimal(p.getStock());
                            mProductoProvider = new productoProvider();
                            mProductoProvider.refreshStock(p.getCodigo(), stockOriginal.add(detalle.get(p.getCodigo())).toString()).addOnSuccessListener(new OnSuccessListener<Void>() {
                                @Override
                                public void onSuccess(Void aVoid) {
                                }
                            });
                        }catch(Exception e){
                            Toast.makeText(comprarProducto.this, "Producto " + data.getKey() + " no existe.", Toast.LENGTH_LONG).show();
                        }
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {
                        System.out.println("The read failed: " + databaseError.getCode());
                    }
                });

            
        }
    }
    @Override
    public void onCancelled(DatabaseError databaseError) {}

});

谢谢。

【问题讨论】:

  • 您已经链接了正确的解决方案,其中涉及调用runTransaction。是什么阻止您在代码中使用它?
  • 是的,我正在考虑将我的代码放入 runTransaction。这会确保代码的正确执行吗?在文档中我看到修改了一个值,但是我想修改MutableData以外的值。
  • 我发现使用 Firebase 事务无法解决我的代码。 Firebase 还有其他替代品吗?
  • 您可以将update 与两个ServerValue.increment() 操作一起使用:firebase.google.com/docs/reference/android/com/google/firebase/…。但在这种情况下,您首先需要将值存储为数字,而不是字符串。

标签: android firebase-realtime-database


【解决方案1】:

我正在使用 updateChildrenServerValue.increment

使用这些路径,您可以通过一次调用 updateChildren() 来同时更新 JSON 树中的多个位置,例如此示例如何在两个位置创建新帖子。以这种方式进行的同时更新是原子的:要么所有更新都成功,要么所有更新都失败。

final Map<String, Object> productUpdates = new HashMap<>();

            Query query = mDatabase.child("COMPRAS").child(key).child("COMPRASPRODUCTO");
            query.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    for(DataSnapshot ds : dataSnapshot.getChildren()){
                        System.out.println("---" + ds.getKey());
                        CompraProducto producto = ds.getValue(CompraProducto.class);
                        productUpdates.put("/PRODUCTO/" + ds.getKey() +"/stock", ServerValue.increment(producto.getCantidad()));
                    }
                    System.out.println("==============");
                    if(!productUpdates.isEmpty()) {
                        mDatabase.updateChildren(productUpdates, new DatabaseReference.CompletionListener() {
                            @Override
                            public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                                if (databaseError == null) {
                                    mCompraProvider.actualizar(key, inputProveedor.getText().toString(), inputFecha.getText().toString(), "PENDIENTE").addOnSuccessListener(new OnSuccessListener<Void>() {
                                        @Override
                                        public void onSuccess(Void aVoid) {
                                            Toast.makeText(comprarProducto.this, "Compra del proveedor " + inputProveedor.getText().toString() + " guardada correctamente.", Toast.LENGTH_SHORT).show();
                                        }
                                    });
                                    System.out.println("onComplete: success");
                                } else {
                                    System.out.println("onComplete: fail" + databaseError.toException());
                                }
                            }
                        });
                    }
                }
                @Override
                public void onCancelled(DatabaseError databaseError) {}

            });

【讨论】:

    猜你喜欢
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 2013-12-22
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多