Home > front end >  Using Transactions but still getting same objects from Firebase
Using Transactions but still getting same objects from Firebase

Time:01-05

I have a Firebase document "coupon" that has 2 fields inside: an array of strings and an integer as seen below

Coupon Firebase Document

Currently if a user clicks on a button to get a coupon, it will remove the 0 index at Firebase and show that removed array as coupon code in a Text widget, but if two or more users click on the button at the same time they all get the same string from the array.

This is my button on click code currently:

try {
  await FirebaseFirestore.instance
      .runTransaction((transaction) async {

    DocumentReference
        couponCollectionReference =
        FirebaseFirestore.instance
            .collection('coupons')
            .doc(widget.couponNumber);

    DocumentReference userCollectionReference =
        FirebaseFirestore.instance
            .collection('users')
            .doc(getUserID());
            
    setState(() {
      couponTitle = couponCode[0];
      couponBlur = 0.0;
      isButtonWorking = false;
    });

    transaction
        .update(couponCollectionReference, {
      'coupon_code': FieldValue.arrayRemove(
          [couponCode[0]]),
    });

    transaction
        .update(couponCollectionReference, {
      'coupons_available':
          FieldValue.increment(-1),
    });

    transaction
        .update(userCollectionReference, {
      'current_points':
          FieldValue.increment(-100),
    });

    await screenshotController
        .capture(
            pixelRatio: 2,
            delay: Duration(milliseconds: 20))
        .then((capturedImage) async {
      ShowCapturedWidget(
          context, capturedImage!);
    }).catchError((onError) {
      print(onError);
    });
  });
} catch (e)

Are transactions the way to go and I'm just not implementing them right or am I using a totally wrong approach ?

CodePudding user response:

In order for the coupon document to be considered part of the transaction, you have to read it from the database through the transaction object (and use the value of coupons from there).

In your code that'd be something like this:

await FirebaseFirestore.instance
    .runTransaction((transaction) async {

  DocumentReference
      couponCollectionReference =
      FirebaseFirestore.instance
          .collection('coupons')
          .doc(widget.couponNumber);

  DocumentSnapshot couponDoc = await transaction.get(couponCollectionReference); //            
  •  Tags:  
  • Related