Skip to content

Commit

Permalink
Support FieldValue.increment (googlearchive#232)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevmoo authored Jul 22, 2019
1 parent 72d0742 commit 8048c4b
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 18 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@

Google Inc.
Jana Moudrá <[email protected]>
Andrew Babin <[email protected]>
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
- **BREAKING** The `Promise` polyfil has been removed from the JS SDK. Users
will have to include their own polyfil for `Promise`.

- Added `FieldValue.increment` static function.

## 5.0.4

- Require at least Dart 2.1.0.
Expand Down
50 changes: 32 additions & 18 deletions lib/src/firestore.dart
Original file line number Diff line number Diff line change
Expand Up @@ -889,19 +889,17 @@ abstract class _Updatable {

class _FieldValueDelete implements FieldValue {
@override
dynamic _jsify() {
return firestore_interop.FieldValue.delete();
}
firestore_interop.FieldValue _jsify() =>
firestore_interop.FieldValue.delete();

@override
String toString() => 'FieldValue.delete()';
}

class _FieldValueServerTimestamp implements FieldValue {
@override
dynamic _jsify() {
return firestore_interop.FieldValue.serverTimestamp();
}
firestore_interop.FieldValue _jsify() =>
firestore_interop.FieldValue.serverTimestamp();

@override
String toString() => 'FieldValue.serverTimestamp()';
Expand Down Expand Up @@ -941,23 +939,25 @@ class _FieldValueArrayRemove extends _FieldValueArray {
String toString() => 'FieldValue.arrayRemove($elements)';
}

class _FieldValueIncrement implements FieldValue {
final num n;

_FieldValueIncrement(this.n);

@override
firestore_interop.FieldValue _jsify() =>
firestore_interop.FieldValue.increment(n);

@override
String toString() => 'FieldValue.increment($n)';
}

dynamic jsifyFieldValue(FieldValue fieldValue) => fieldValue._jsify();

/// Sentinel values that can be used when writing document fields with set()
/// or update().
abstract class FieldValue {
factory FieldValue._fromJs(dynamic jsFieldValue) {
if (jsFieldValue == firestore_interop.FieldValue.delete()) {
return FieldValue.delete();
} else if (jsFieldValue == firestore_interop.FieldValue.serverTimestamp()) {
return FieldValue.serverTimestamp();
} else {
throw ArgumentError.value(jsFieldValue, 'jsFieldValue',
"Invalid value provided. We don't support dartfying object like arrayUnion or arrayRemove since not needed");
}
}

dynamic _jsify();
firestore_interop.FieldValue _jsify();

/// Returns a sentinel used with set() or update() to include a
/// server-generated timestamp in the written data.
Expand Down Expand Up @@ -989,6 +989,20 @@ abstract class FieldValue {
static FieldValue arrayRemove(List elements) =>
_FieldValueArrayRemove(elements);

/// Returns a special value that can be used with set() or update() that tells
/// the server to increment the field's current value by the given value.
/// If either the operand or the current field value uses floating point
/// precision, all arithmetic follows IEEE 754 semantics. If both values
/// are integers, values outside of JavaScript's safe number range
/// (Number.MIN_SAFE_INTEGER to Number.MAX_SAFE_INTEGER) are also subject
/// to precision loss. Furthermore, once processed by the Firestore backend,
/// all integer operations are capped between -2^63 and 2^63-1.
/// If the current field value is not of type number, or if the field does not
/// yet exist, the transformation sets the field to the given value.
static FieldValue increment(num n) => _FieldValueIncrement(n);

FieldValue._();

static final FieldValue _serverTimestamp = _FieldValueServerTimestamp();
Expand Down
2 changes: 2 additions & 0 deletions lib/src/interop/firestore_interop.dart
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ abstract class FieldValue {
/// server-generated timestamp in the written data.
external static FieldValue serverTimestamp();

external static FieldValue increment(num n);

/// Returns `true` if this [FieldValue] is equal to the provided [other].
external bool isEqual(Object other);
}
Expand Down
23 changes: 23 additions & 0 deletions test/firestore_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,29 @@ void main() {
expect(timeStamp, isA<DateTime>());
});

test('increment', () async {
var docRef = ref.doc("increment");

await docRef.set({
'increment': {'int': 1, 'double': 3.141, 'nonnumber': 'firebase'}
});

await docRef.set({
'increment': {
'int': fs.FieldValue.increment(100),
'double': fs.FieldValue.increment(1.618),
'nonnumber': fs.FieldValue.increment(42)
}
}, fs.SetOptions(merge: true));

var snapshot = await docRef.get();
var snapshotData = snapshot.data();

expect(snapshotData, {
"increment": {'int': 101, 'double': 4.759, 'nonnumber': 42}
});
});

test("update nested with dot notation", () async {
var docRef = await ref.add({
"greeting": {"text": "Good Morning"}
Expand Down

0 comments on commit 8048c4b

Please sign in to comment.