Home > Blockchain >  Is there a way to avoid a Firestore field from reaching a negative value?
Is there a way to avoid a Firestore field from reaching a negative value?

Time:05-02

I have an app where a Firestore field value decreases by 45 every time a specific button is pressed. I achieved this by using Firestore's FieldValue.increment() as shown below:

FirebaseFirestore.instance.collection('users').get().then((_) async {
    await FirebaseFirestore.instance.collection('users').doc(uid).update({
        "example": FieldValue.increment(-45),
    });
});

The problem is that I can't let the field example reach less than zero. I tried using the .where() method, but it doesn't apply for specific documents, in this case, the current user document.

Future<void> example() {
    return FirebaseFirestore.instance
        .collection('users')
        .where('example', isLessThan: 45)
        .get()
        .then(((value) {
      print('subtracting results in a negative value');
    }));
  }

As it is clearly stated in the documentation, "only documents satisfying provided condition are included in the result set", it is evident that document-specific queries cannot be made, therefore my problem cannot be solved this way.

Ideally, an if condition where a field reference meets the condition (< 45) would solve the problem, but as far as I'm concerned, Firestore doesn't currently support a FieldReference, as opposed to CollectionReference and DocumentReference.

I'm relatively new to Flutter and I've been working with Firebase since quite recently, so any help and/or advice is greatly appreciated :)

CodePudding user response:

You can get the doc reference first, check the value and only increment if it complies with the if.

I do not come from Dart language background so feel free do correct the syntax. But hopefully you will get an idea.

Ex:

final userRef = await FirebaseFirestore.instance.collection('users').doc(uid)
userRef.get().then(res=>{
  if(res.example > 45){
    userRef.update({
      "example": FieldValue.increment(-45),
    })
  }
})

CodePudding user response:

Instead of (or maybe in addition to) doing this in your code, I recommend doing it in Firebase's security rules. Since these rules are enforced on the server, there is no way for even a malicious client to circumvent then.

To validate that the example field never becomes negative, you can do:

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{user} {
      allow write: if request.resource.data.example > 0;
    }
  }
}
  • Related