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')
)



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.












