6

In MongodDB , There is a data type "Decimal128" which holds the value of a decimal correctly ( see the "why" Here.

What is the recommended way to store / use decimal and money types in firebase? Convert to and from Bigdecimal? Or is the decimal type in firestore sufficient for overcoming rounding issue?

Martin Thompson
  • 3,415
  • 10
  • 38
  • 62

4 Answers4

6

According to the documentation, Firestore's floating point type is 64-bit double precision, IEEE 754. This format has imprecision due to rounding. There is no "decimal" format in Firestore as you find with other databases. And there is no formally recommended type for monetary values in Firestore, so you should look into other ways of representing them in some other way. A web search may help you with that.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • 11
    Thanks. After much reading , I have decided on Strings! Seems ridiculous at this point in time when technology is so advanced. – Martin Thompson Feb 04 '19 at 18:30
2

As @Doug notes, floating point imprecision makes double unsuitable for storing currency (or any other decimal values that require consistency), particularly if you want to do any math on these stored values.

While your solution to use String type to store decimals will work, it might cause issues if performing math later.

One alternative is to store currency as int 'cents', then divide by 100 when displaying to the user – and thus multiple by 100 before storing user input.

For example, although as double floats:

print(0.2 + 0.1);
= 0.30000000000000004

Instead as int x 100:

int x = 20;
int y = 10;
print((x+y)/100);
= 0.3

This might get unwieldy if your project makes use of many different currency fields, but for most things there's a certain simplicity and transparency to using int x100 for base-100 currencies that I think keeps code predictable.

djoll
  • 1,139
  • 1
  • 12
  • 31
2

I'd go with a similar approach like @djoll has mentioned, a common thing we do at Google is to store amount_micros instead of amount, which means for $1 you'd store 1,000,000 as int. It's much easier to perform math this way.

E. Sun
  • 1,093
  • 9
  • 15
-2

If you want your int (say the number 350) to have decimals, you could add '.00' to the end of it on the client-side. For example, in Angular 2+ you can use the decimal pipe, like so:

  {{350 | number:'3.2-5'}}
  <!--output: '350.00'-->
New-Way
  • 507
  • 3
  • 12