0

I am trying to make an application on Android, I am a beginner.

My realtime database

I try to increment the "stock" of a product, but my following code is not reliable. I had connection problems on the device and the "stock" did not increase correctly. How can I execute it as a transaction?. I cannot find extensive documentation.

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) {}

});

Thank you.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Cesarvv
  • 1
  • 3
  • You've already linked the correct solution, which involves calling `runTransaction`. What is keeping you from using that in your code? – Frank van Puffelen Feb 10 '21 at 02:56
  • Yes, I was thinking of putting my code inside runTransaction. Will this ensure the correct execution of the code? In the documentation I see that one value is modified, but I want to modify values ​​other than MutableData. – Cesarvv Feb 10 '21 at 03:08
  • I see that with Firebase transactions it is not possible to solve my code. Is there another alternative to Firebase? – Cesarvv Feb 10 '21 at 11:51
  • You could use an `update` with two `ServerValue.increment()` operations: https://firebase.google.com/docs/reference/android/com/google/firebase/database/ServerValue#increment(long). But in that case you'll first need to store the values as numbers, instead of strings. – Frank van Puffelen Feb 10 '21 at 16:18

1 Answers1

0

I am using updateChildren and ServerValue.increment

Using these paths, you can perform simultaneous updates to multiple locations in the JSON tree with a single call to updateChildren(), such as how this example creates the new post in both locations. Simultaneous updates made this way are atomic: either all updates succeed or all updates fail.

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) {}

            });
Cesarvv
  • 1
  • 3