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