[Realm React, Typescript] bsonType: [double,null], given: [integer int long number mixed]

I am using Realm React SDK with typescript. I have a field that is defined as GeoPoint on my schema located on the Mongo Atlas. in there, there is a field named coordinates that is defined as double.

However, there is chance that a coordinate is a flat number, i.e. 150. In that case, when I try to set that number of my typescript with type number. The server side will reject my insert request with the message of Invalid type. Expected: type: undefined, bsonType: [double,null], given: [integer int long number mixed]

How can I convert the number 150 to double so that the server will not reject my insert.

We made need some clarity; you’ve got a field called ‘coordinates’ (plural) but it only stores one double value, is that correct?

Internally, both a double and an int map to a Java Number so the reason for the error is not clear. But, what’s being assigned doesn’'t appears to match the error.

Can you please update your question to include your model and the code you’re attempting to use to write to that model?

1 Like

For sure. I have created a simple collection that can repro this issue.

Create a collection test with a validation schema: (Note that the type of geoLocation is GeoPoint)

{
  "properties": {
    "geoLocation": {
      "bsonType": "object",
      "properties": {
        "type": {
          "bsonType": "string"
        },
        "coordinates": {
          "bsonType": "array",
          "items": {
            "bsonType": "double"
          }
        }
      },
      "required": [
        "type"
      ]
    },
    "_id": {
      "bsonType": "objectId"
    }
  }
}

Then on the client side (react native), try to insert a new record that have int.

await mongoUser.mongoClient('mongodb-atlas').db('main').collection('test').insertOne({
    geoLocation: {
      type: 'Point',
      coordinates: [1.0, 2.0],
    }
  });

The insert will failed with message insert not permitted. When go to Mongo Atlas log, I can see error with the message

role "readAndWriteAll" in "main.test" does not have insert permission: could not validate document: geoLocation.coordinates.0: Invalid type. Expected: type: undefined, bsonType: [double,null], given: [integer int long number mixed] geoLocation.coordinates.1: Invalid type. Expected: type: undefined, bsonType: [double,null], given: [integer int long number mixed]

Now the question is that, what can I do on the react client side so that the number can be understand as a double.

Hi, sorry to hear about this. I think there are a few things we can do on our side to make this better, but first I will try to troubleshoot to get this working for you.

Right now we only support GeoPoints that are of type Double. It seems that you are running into a known “feature” (I put it in quotes because I agree it is odd) that the NodeJS driver will always make a numeric type the smallest type that can be represented (in this case an integer). You can force the driver to send specific types though and they are exported in the package:

const { Double } = require('bson');
const value = new Double(1);

See the docs here: mongodb
And the code here: https://github.com/mongodb/js-bson/blob/77fac2a369c9009e88604a9dce0c688778826973/src/double.ts

Therefore, I think if you wrap your script with a “Double” it should solve your problems.

On our end, I will file 2 tickets as action items from this:

  1. We should make this error easier to read
  2. We should consider supporting integers being passed as GeoPoints and just converting them into Doubles when possible (we do this for non-geo point fields specified as doubles)

Best,
Tyler

Hi Tyler,

Thank you for your suggestion. However, when I try the workaround, I same error message are raise and I still not able to add the int number.

import {Double} from 'bson';
try {
  await mongoUser.mongoClient('mongodb-atlas').db('main').collection('test').insertOne({
    geoLocation: {
      type: 'Point',
      coordinates: [new Double(1.0),  new Double(2.0)],
    },
  });
} catch (e) {
  logger.error(e);
}

Hi, I did not realize you are running this within an app-services function. Can you try using this: https://www.mongodb.com/docs/atlas/app-services/functions/globals/#mongodb-method-BSON.Double

If that does not work can you post the exact error you are seeing (or is it the exact same thing?) and a link to your application (the URL).

Best,
Tyler

Hi,

I am actually using the Realm React Native SDK.

As for your suggestion, that is very interesting. For some reason, Double is not exported vai the BSON

import {BSON} from 'realm';

const test = new BSON.Double(1.0);

This will raise error TS2339: Property Double does not exist on type typeof BSON.

However, they do export Decimal128. Not sure if that is the same as double.

Okay, got it. Was a bit hard to decipher where this was running. Do you have a link to your application? And could you just modify the schema to allow integers / mixed? I can chat with the Javascript team but wrapping it in the original bson.Double() should work.

I don’t have a link to my application because it is being developed for mobile devices.

I can not modify the schema because of the preset of GeoPoint. Once I select the type to be GeoPoint, the coordinates are auto-generated with the type double and cannot be modified.

Should I open this as an issue on react-js repo on github?