skip to Main Content

I’m experiencing an issue with Firestore’s FieldValue.increment() function when using large integer values. The increment works correctly for smaller numbers, but it produces incorrect results, even negative values, for numbers above approximately 2148 million (2148000000).

I have the following code that increments a counter called test within the Firestore database. The increment function works perfectly for small incrementValue numbers. However, from the number 2148 million (2148000000) onwards, a calculation error occurs and the increment can even give negative values. I’m using 0 as a starting test value in Firestore. Here are some examples of the results:

Example 1:

  • Initial test value in Firestore = 0
  • Increment Value = 1000
  • Expected Result = 1000
  • Final test value in Firestore = 1000 (Ok)

Example 2:

  • Initial test value in Firestore = 0
  • Increment Value = 2148000000
  • Expected Result = 2148000000
  • Final test value in Firestore = -2146967296 (Error)

Example 3:

  • Initial test value in Firestore = 0
  • Increment Value = 10000000000
  • Expected Result = 10000000000
  • Final test value in Firestore = 1410065408 (Error)

Code:

      Future<bool> incrementTest() async {
        
        WriteBatch batch = db.batch();
    
        int incrementValue  = 2148000000;
    
        DocumentReference doc = db
          .collection('testing')
          .doc('increment');
    
        batch.update(doc, {
          'test':  FieldValue.increment(incrementValue),
        });
        log('Test incrementValue: $incrementValue');
    
        try {
          await batch.commit();
          return true;
        } catch (e) {
          log('$e');
          return false;
        }
      }

Observations:

  • The issue persists with both WriteBatch and direct doc.update()
    operations.
  • Firebase documentation states a limit of -2^63 to 2^63-1 for
    integer operations, which is much higher than the problematic
    value.
  • The exact value where the error begins to appear is 2147483648 which is equivalent to 2^32 / 2 (32-bit signed integer)

Questions:

  • Is there a specific limitation on Firestore’s increment function
    that’s causing this behavior?
  • How can I reliably increment counters with values potentially
    exceeding 2148 million while avoiding this error?

2

Answers


  1. i think the problem is not with the firebase but is limited to Dart ,

    as a fact that the maximum value that can be represented by a 32-bit signed integer is 2147483647 .
    the sane is causing the issue here ,as in Dart the default data type for integers is int, which is a 32-bit signed integer.

       Future<bool> incrementTest() async {
       // WriteBatch batch = db.batch();
      
        Int64 incrementValue = Int64(2148000000); //here use the Int64 data type 
      
        DocumentReference doc = db.collection('testing').doc('increment');
      
        await transaction.update(doc,{
          'test' : incrementValue+1
        });
        log('Test incrementValue: $incrementValue');
      
        try {
          await batch.commit();
          return true;
        } catch (e) {
          log('$e');
          return false;
        }
      }
    

    i am currently unable to run this in flutter environment so i welcome any suggestion by any one .

    Login or Signup to reply.
  2. Is there a specific limitation on Firestore’s increment function that’s causing this behavior?

    I was unable to reproduce the problem (your second test case) at all using firebase-admin on nodejs, both on the emulator and the actual cloud service. This leads me to believe that the problem is likely with the Flutter SDK and not the Firestore service itself. You should file a bug with your steps to reproduce on the Firebase Flutter SDK GitHub. You can see the source code yourself here if you want to dig in further and propose a specific change.

    How can I reliably increment counters with values potentially exceeding 2148 million while avoiding this error?

    If the increment operation doesn’t work the way you expect, you can perform an atomic increment by using a transaction. This will let you read the document, modify the number in memory, then write the modified value back to the document. If you don’t need the update to be atomic, then don’t even bother with the transaction, and just read/modify/write the document as you would normally.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search