firebase / firebase/firebase-tools
[firestore-emulator: datastore-mode] Unexpected response from query filter on nested property in array
- Dominant language
- TypeScript
- Stars
- 4.5k
- Forks
- 1.3k
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 84
Description
### [REQUIRED] Environment info
**gcloud:** v493.0.0
**Platform:** Ubuntu
### [REQUIRED] Test case
**package.json**
```json
{
"version": "1.0.0",
"description": "",
"main": "lib/index.js",
"scripts": {
"build": "tsc",
"start": "DATASTORE_EMULATOR_HOST=127.0.0.1:8080 node lib/index.js",
"start:emulator:old": "gcloud --project=dummy-project-id beta emulators datastore start --use-firestore-in-datastore-mode --host-port=127.0.0.1:8080",
"start:emulator:new": "gcloud emulators firestore start --database-mode=datastore-mode --host-port=127.0.0.1:8080"
},
"devDependencies": {
"@google-cloud/datastore": "^9.1.0",
"typescript": "^5.4.3"
}
}
```
**src/index.ts**
```ts
import {and, Datastore, PropertyFilter} from "@google-cloud/datastore";
const datastore = new Datastore({
projectId: "dummy-project-id",
});
const KIND_USER = 'User'
type User = {
email: string
fields : {
key: string,
value: string,
}[]
}
export async function getUsersByName(name: string) {
const query = datastore.createQuery(KIND_USER).filter(and([
new PropertyFilter('fields.key','=','name'),
new PropertyFilter('fields.value','=',name),
]));
const [entities] = await datastore.runQuery(query);
return entities
}
export async function addUser(data: User) {
const key = datastore.key(KIND_USER);
const entity = {
key: key,
data,
};
await datastore.save(entity);
}
async function main() {
await addUser({email: "foo@example.com", fields: [{key: "name", value: "Awesome Name"}]})
const users = await getUsersByName("Awesome Name");
console.log(users);
}
main();
```
**tsconfig.json**
```json
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"outDir": "lib"
},
"include": ["src"],
"exclude": []
}
```
### [REQUIRED] Steps to reproduce
**Datastore Emulator (Old)**
```
npm install
npm run start:emulator:old
```
```
$ npm run build && npm run start
> build
> tsc
> start
> DATASTORE_EMULATOR_HOST=127.0.0.1:8080 node lib/index.js
[
{
fields: [ [Object] ],
email: 'foo@example.com',
[Symbol(KEY)]: Key {
namespace: undefined,
id: '1',
kind: 'User',
path: [Getter]
}
},
]
```
**Firestore Emulator (New, Preview)**
```
npm install
npm run start:emulator:new
```
```
$ npm run build && npm run start
> build
> tsc
> start
> DATASTORE_EMULATOR_HOST=127.0.0.1:8080 node lib/index.js
[]
```
### [REQUIRED] Expected behavior
```
[
{
fields: [ [Object] ],
email: 'foo@example.com',
[Symbol(KEY)]: Key {
namespace: undefined,
id: '1',
kind: 'User',
path: [Getter]
}
},
]
```
### [REQUIRED] Actual behavior
The result filtered by `fields.name` and `fields.value` should include the user, but not when using the new emulator.
```
[]
```
This issue slightly differs from https://github.com/firebase/firebase-tools/issues/6999, as the `fields` property is an array here.
Contributor guide
Assessment
This issue has not been assessed yet.