Skip to main content

Query

This page discusses how query works.

Type Checks

import {
MetaTypeCreator,
ServerTimestamp,
NumericKeyRecord,
Removable,
createRef,
getDatabase,
query,
PushAbleOnly,
orderByValue,
endBefore,
startAt,
limitToFirst,
startAfter,
endAt,
limitToLast,
orderByKey,
orderByChild,
equalTo,
} from 'firesagejs'

export type Example = MetaTypeCreator<{
b:
| {
c: boolean | Removable
d: {
e: ServerTimestamp
}
}
| Removable
f: Record<string, 1 | 2 | 3 | 4 | 5>
i: NumericKeyRecord<boolean>
j: PushAbleOnly<{ k: null; l: { j: number } }>
}>

const exampleRef = createRef<Example>(getDatabase()) // firesage ref
/*
=======
OK
=======
*/
query(
exampleRef('f'),
orderByValue(),
// 1st argument type is the type of node 'f' child
// 2nd argument is optional, the type is type of key
// the type of key can only be numeric string or non-numeric string
// in this case the type of 2nd argument is numeric string because the type of 'f' is Record<string, 1 | 2 | 3 | 4 | 5>
startAt(1, 'xyz'),
endBefore(5),
limitToFirst(2)
)

query(
exampleRef('i'),
orderByKey(),
// when orderbyKey, the type of 1st argument is the type of key
// the type of key can only be numeric string or non-numeric string
// in this case it is numeric string because the type of 'i' is NumericKeyRecord<boolean>
// no 2nd argument
startAfter('24'),
endAt('100'),
limitToLast(5)
)

query(
exampleRef('j'),
// relative path must start at grandchildren which is 'k','l' and 'l/j'
// 'l' however is not valid because the type of 'l' is object literal and cannot be ordered
orderByChild('l/j'),
// 1st argument type is the type of node 'l/j' child
// 2nd argument is optional, the type is type of key
// the type of key can only be numeric string or non-numeric string
// in this case the type of 2nd argument is numeric string because the type of 'f' is Record<string, 1 | 2 | 3 | 4 | 5>
equalTo(1, 'abc')
)
/*
=======
not OK
=======
*/
query(
// can only order by node with one signature children
// b has 2 children with different signatures
exampleRef('b')
)

query(
exampleRef('f'),
// must has one orderBy to use cursor
startAt(1)
)

query(
exampleRef('f'),
orderByValue(),
// not ok, duplicated cursor
startAt(1, 'xyz'),
startAt(1, 'xyz'),
limitToFirst(2)
)

query(
exampleRef('f'),
orderByValue(),
// not ok, you cant combine startAt and startAfter
startAt(1, 'xyz'),
startAfter(1, 'xyz'),
limitToFirst(2)
)

query(
exampleRef('f'),
orderByValue(),
// not ok, you cant combine endAt and endBefore
endAt(1, 'xyz'),
endBefore(5),
limitToFirst(2)
)

query(
exampleRef('f'),
orderByValue(),
// not ok, you cant combine equalTo and any other cursor
equalTo(1, 'xyz'),
endBefore(5),
limitToFirst(2)
)

query(
exampleRef('f'),
orderByValue(),
startAt(1, 'abc'),
// not ok, incorrect value type, expect number
endBefore(true),
limitToFirst(2)
)

query(
exampleRef('i'),
orderByKey(),
// not ok, orderByKey don't need 2nd argument
startAfter('24', 'someKey'),
endAt('100'),
limitToLast(5)
)

query(
exampleRef('i'),
orderByKey(),
// not ok, when orderByKey the 1st argument must be the type of key
// in this case, expect numeric string
startAfter(false),
endAt('100'),
limitToLast(5)
)

query(
exampleRef('j'),
// not ok, path must start at grandchild path
orderByChild('childPath')
)

query(
exampleRef('j'),
// not ok, type of 'j/${string/}l' is object literal and cannot be ordered
orderByChild('l')
)
image 1

image 2

image 3

Understanding Error Messages

note

We can only query index signature.

The value type for all keys must be the same, example: Record<string, T>.

If you have data type like {a:number, b:boolean, c:string, d:boolean, e:string}, it doesn't make sense to order them.

RTDB wont throw error if we violate this rule but this not a good practise.

We should always group similar things together.

we should only order index signature

cursors need at least one orderBy*

cursors must be unique*

don't use startAt with startAfter

don't use endAt with endBefore

don't use equalTo with all other cursors

incorrect value type

no 2nd argument when order by key

when order by key, the first argument must be numeric or non numeric string

expect numeric string

expect non-numeric string

illegal child or did not start at grandchild path

there can be only 1 orderBy* clause