How to Decrease a Value Using Fieldvalue in Firestore (Swift)

How to decrease a value using FieldValue in Firestore (SWIFT)?

There is no need for a decrement function, simply pass a negative value to the actual increment() function:

document("fitness_teams/Team_1").
updateData(["step_counter" : FieldValue.increment(-500)])

And the value of your step_counter field will be decremented by 500.

Stop counter min value at 0 when using Firstore Fieldvalue increment function

A transaction is actually the right way to go here, since you can check the bounds of the value. FieldValue.increment() can't do that.

However, if you want to update to simply fail when provided with invalid values, you can use Firestore security rules to validate the field value. These rules only work when directly accessed by web and mobile clients. They don't apply to backend code.

Firestore - How to decrement integer value atomically in database?

To decrement the value in a field, do a negative increment. So:

FieldValue.increment(-50)

Firestore fieldvalue.increment using setData does not increment the value, while updateData does

"set" type operations overwrite existing data by default, so it's working the way you expect. It does not consider the values of any existing fields.

If you add the "merge" option to setData, then only the specified fields will get updated, and everything else will stay the same, like update. See the documentation for setData.

ref.setData(data, true)  // merge is true here

How to increment existing number field in Cloud Firestore

Firestore now has a specific operator for this called FieldValue.increment(). By applying this operator to a field, the value of that field can be incremented (or decremented) as a single operation on the server.

From the Firebase documentation on incrementing a numeric value:

var washingtonRef = db.collection('cities').doc('DC');
// Atomically increment the population of the city by 50.
washingtonRef.update({
population: firebase.firestore.FieldValue.increment(50)
});

So this example increments the population by 50, no matter what is current value is. If the field doesn't exist yet (or is not a number), it is set to 50 in this case.


If you want to decrement a number, pass a negative value to the increment function. For example: firebase.firestore.FieldValue.increment(-50)

Increment existing value in firebase firestore

Thanks to the latest Firestore patch (March 13, 2019)

Firestore's FieldValue class now hosts a increment method that atomically updates a numeric document field in the firestore database. You can use this FieldValue sentinel with either set (with mergeOptions true) or update methods of the DocumentReference object.

The usage is as follows (from the official docs, this is all there is):

DocumentReference washingtonRef = db.collection("cities").document("DC");

// Atomically increment the population of the city by 50.
washingtonRef.update("population", FieldValue.increment(50));

If you're wondering, it's available from version 18.2.0 of firestore. For your convenience, the Gradle dependency configuration is implementation 'com.google.firebase:firebase-firestore:18.2.0'

Note: Increment operations are useful for implementing counters, but
keep in mind that you can update a single document only once per
second. If you need to update your counter above this rate, see the
Distributed counters page.


FieldValue.increment() is purely "server" side (happens in firestore), so you don't need to expose the current value to the client(s).

Removing an array item from Firestore

You have to use arrayRemove to remove items from arrays.

@objc func removeItem() {
let docRef = FirestoreReferenceManager.simTest.document("abc")

docRef.getDocument { (document, error) in
do {
let retrievedTestGroup = try document?.data(as: TestGroup.self)
let retrievedTestItem = retrievedTestGroup?.items[1]
guard let itemToRemove = retrievedTestItem else { return }
docRef.updateData([
"items" : FieldValue.arrayRemove([["title" : itemToRemove.title,
"color" : itemToRemove.color,
"number" : itemToRemove.number]])
]) { error in
if let error = error {
print("error: \(error)")
} else {
print("successfully deleted")
}
}

} catch {

}
}
}

I've encountered situations where this straightforward approach didn't work because the item was a complex object, in which case I first had to query for the item from Firestore and plug that instance into arrayRemove() to remove it.

The reason your approach doesn't have any side effects is because arrays in Firestore are not like arrays in Swift, they are hybrids of arrays and sets. You can initialize an array in Firestore with duplicate items but you cannot append arrays using arrayUnion() with duplicate items. Trying to append a duplicate item using arrayUnion() will silently fail, such as in your case.

Cloud Firestore , nodejs (cloud functions), synchronize access

How do I make sure the counter value didn't change by other party, between the read and write action?

There are two ways in which you can solve this problem.

The first one would be to use a transaction, which is an operation where you read a value from a document, you increment it and then write the document back.

The second solution would be to use the FieldValue.increment(50) operator:

An increment operation increases or decreases the current value of a field by the given amount. If the field does not exist or if the current field value is not a numeric value, the operation sets the field to the given value.

If you need at some point in time to decrement a value, simply pass a negative value to the increment() function:

  • How to decrease a value using FieldValue in Firestore (SWIFT)?


Related Topics



Leave a reply



Submit