🔥High Precision Typescript Wrapper for Firestore Web, Providing Unparalleled Type Safe and Dev Experience
MIT License
Published by tylim88 about 1 year ago
/**
* Gets a {@link CollectionReference} instance that refers to the collection at
* the specified absolute path.
*
* related documentations:
* - {@link https://firelordjs.com/guides/metatype child meta type}
* - {@link https://firelordjs.com/quick_start#operations operation}
* @param documentIds
* All the docID(s) needed to build this document path, eg
* - for top-collection: example.collection()
* - for sub-collection: example.collection(GrandParentDocId, ParentsDocId)
*
* @returns The {@link CollectionReference} instance.
*/
/**
* related documentations:
* - {@link https://firelordjs.com/quick_start/#query query}
* - {@link https://firelordjs.com/quick_start/#onsnapshot onSnapshot}
* @returns — The created {@link Query}.
*/
Published by tylim88 about 1 year ago
expose types Unsubscribe and OnSnapshot
Published by tylim88 over 1 year ago
/**
* listen to filtered collection, entire collection or single document
*
* Attaches a listener for {@link DocumentSnapshot} Or {@link QuerySnapshot} events. You may either pass
* individual {@link onNext} and {@link onError} callbacks. The listener can be cancelled by
* calling the function that is returned when {@link OnSnapshot} is called.
*
* related documentation:
* - {@link https://firelordjs.com/quick_start#onsnapshot}
*
* @param reference
*
* Type 1: {@link Query} eg: query(example.collection(...), ...) listen to filtered collection
*
* Type 2: CollectionGroup({@link Query}) eg: query(example.collectionGroup(...), ...) listen to filtered {@link Query}
*
* Type 3: {@link CollectionReference} eg: example.collection(...) listen to entire collection
*
* Type 4: CollectionGroup({@link Query}) reference eg: example.collectionGroup(...) listen to entire {@link Query}
*
* Type 5: {@link DocumentReference} eg: example.doc(...) listen to a single document
* @param onNext - A callback to be called every time a new {@link DocumentSnapshot} or {@link QuerySnapshot} is available.
*
* Type 1: receive {@link DocumentSnapshot} if {@link reference} is {@link DocumentReference} eg: (value: {@link DocumentSnapshot}) => { handle data here }
*
* Type 2: receive {@link QuerySnapshot} if {@link reference} is CollectionGroup or {@link Query} or {@link CollectionReference} eg: (value: {@link QuerySnapshot}) => { handle data here }
*
* @param onError - optional parameter.
*
* Type 1: a callback to be called if the listen fails or is cancelled. No further callbacks will occur. Eg: (error: {@link FirestoreError})=> { handle error here}
*
* Type 2: {@link SnapshotListenOptions} eg: { includeMetadataChanges: boolean }
* @param options - optional parameter. If {@link onError} is {@link SnapshotListenOptions} eg: { includeMetadataChanges: boolean }, then this argument is never. Else it is {@link SnapshotListenOptions} eg: { includeMetadataChanges: boolean }
* @returns An unsubscribe function that can be called to cancel
* the snapshot listener.
*/
Published by tylim88 over 1 year ago
Object unions type was banned before v2.6.2 because it brings uncertainty that cannot be handled reasonably. For example, with {a:number}|{b:string}, you can set {a:1} then update {b:"x"}, in this case the type is no longer unions type but an intersection type: {a:number} & {b:string}. The reason I decided to lift the limitation is that I believe we should value functionalities over less practical strict typing. Plus in future update operation Mandatory Field could mitigate this problem.
Published by tylim88 over 1 year ago
/**
* Gets a `DocumentReference` instance that refers to the document at the
* specified absolute path.
*
* @param documentIds_or_CollectionReference
* Option 1: all the docID(s) needed to build this document path, eg
* - for top-collection: example.doc(SelfDocId)
* - for sub-collection: example.doc(GrandParentDocId, ParentsDocId, SelfDocId).
*
* Option 2: CollectionReference (to create auto id doc ref), eg
* - for top-collection: example.doc(example.collection())
* - for sub-collection: example.doc(example.collection(GrandParentCollectionID, ParenCollectionID))
*
*
* documentation:
* {@link https://firelordjs.com/guides/metatype child meta type}
* {@link https://firelordjs.com/quick_start#operations operation}
* @returns The `DocumentReference` instance.
*/
{
"rules": {
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-redundant-type-constituents": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-unsafe-member-access": "off"
}
}
v2.6 will focus on improving JSDoc
Published by tylim88 over 1 year ago
(Web only)
Error: You can't order your query by a field included in an equality '==' or 'in' clause. Exceptions to this rule are order by '__name__' or 'documentId()'
because firebase v10.0.0 removed this limitation. I think dev exp is better with this rule but the removal is harmless,side note: If you are using @firebase/rules-unit-testing for testing, you have to use @firebase/rules-unit-testing v3. Firebase v10 does not work with v2 (peer dependency issue)
Published by tylim88 over 1 year ago
make getFirelord
tree shakable
https://firelordjs.com/guides/tree_shaking_getFirelord
const getFirelord = getFirelordShakable({
// all properties are optional
// choose what to keep
orCreator,
andCreator,
docCreator,
collectionCreator,
collectionGroupCreator,
})
const example = getFirelord<Example>(db, 'someCollectionId')
Published by tylim88 over 1 year ago
internal:
documentId()
in test with __name__
Published by tylim88 over 1 year ago
unionReadTimestampWithNull
Published by tylim88 over 1 year ago
Record<string, something>
data typetransaction.updateNoFlatten
, batch.updateNoFlatten
, and updateDocNoFlatten
.for more details see https://github.com/tylim88/Firelord/releases/tag/2.4.16
Published by tylim88 over 1 year ago
You can use at most one array-contains or array-contains-any clause per query. You can't combine array-contains with array-contains-any
this is because or
query allows multiple array-contains
or array-contains-any
clauses but and
query does not throw runtime error:
or(where('a', 'array-contains-any', ['2']),where('a', 'array-contains', '1'))
will throw runtime error error:
and(where('a', 'array-contains-any', ['2']),where('a', 'array-contains', '1'))
Solution exist but because of composite query nesting, it is going to be very complicated
I decided not to works on this for now, plus I am sick due to dengue
Published by tylim88 over 1 year ago
-if there is only one clause in or()
query, will NOT throw Error: You cannot use 'not-in' in 'or' query, nested or not. But can be neighbor in 'and' query , eg: and(where('a','not-in',[1]), or(where('b','>',2), where('c','<',1)))
type error
or(where('...', 'not-in', ['...'])) //will not throw
or(where('...', 'not-in', ['...']), where('...', '...', '...')) // will throw the type error
Published by tylim88 over 1 year ago
-(internal)remove AddSentinelFieldPathToCompare
, RemoveSentinelFieldPathFromCompare
and AddSentinelFieldPathToCompareHighLevel
They were poorly designed and have been replaced by a simpler solution. The type AddSentinelFieldPathToCompare
will no longer appear in error messages
Published by tylim88 over 1 year ago
documentId()
now return 'name', this is to simplify the typing logic. documentId
field value is probably meaningless right now as we could just use __name__
, but will keep it for backward compatibility
fix when orderby documentId, the cursor require full document path regardless of whether the reference is collection reference or collection group reference.
old behavior
query(colRef, orderBy(documentId()), endAt('abc')) // error: require full document path, eg 'a/b', reject plain document id <--incorrect behavior
query(colGroupRef, orderBy(documentId()), endAt('a/b') // ok, accept full document path and reject plain document id
new behavior
query(colRef, orderBy(documentId()), endAt('abc')) // ok, now need only plain document id and reject full path
query(colGroupRef, orderBy(documentId()), endAt('a/b') // ok, accept full document path and reject plain document id
the logic behind these type rules:
Published by tylim88 over 1 year ago
-update an error message
-fix where
clause return non-descriptive never
error on incorrect field path type, example
the bug:
now work as expected
Published by tylim88 over 1 year ago
2.5.2
GetDocIds
and GetCollectionIds
, useful if you want to abstract document id and collection id, see https://firelordjs.com/guides/abstractdocandcolids/
2.5.3
previously query(collectionRef, where(documentId(), '!=', 'a' as string))
always error, now only throw if document id type is string literal(not wide type string)
Published by tylim88 over 1 year ago
__name__
for filter field path, eg: where('__name__', '==', 'something')
is now error freedocumentId()
for orderBy
field, orderBy(documentId())
is now error freesummary: with these 2 changes, you can use both documentId()
and __name__
for orderBy
and where
clause
update You can't order your query by a field included in an equality (==) or (in) clause
ruling: query(ref, orderBy(x), where(x, '==', 'something'))
is now error free, where x
is documentId()
or __name__
. This is a special case.
tons of housekeeping, refactoring and improvements
mirror API of Firestore or
& and
query
query(
example.collection(),
example.or(
where('f.h', '>', 2929),
where('a', '==', 1),
// you can nest composite query https://firebase.google.com/docs/firestore/query-data/queries#disjunctive_normal_form
example.and(
where('f.g', 'in', [new Date(999), new Date(3000)]),
where('b.d', 'array-contains', { e: 'a' })
)
)
)
nested composite rulings are ready, example:
It has all the normal query rulings plus new rulings specified to composite query.
This was very difficult to create. I had to leave out many details in this release note due to the large number of changes.
Published by tylim88 over 1 year ago
in
combination, this was not possible before v9.17.2query(ref, where('a', 'in', [1]), where('b', 'in', [2])) // now it is possible!
in
and array-contains-any
combination, this was not possible before v9.17.2 https://github.com/firebase/firebase-js-sdk/issues/7147
query(ref, where('a', 'in', [1]), where('b', 'array-contains-any', [2])) // now it is possible!
or
and and
query: https://firebase.google.com/docs/firestore/query-data/queries#or_queries
these updates do not apply to admin as admin haven't catch up to web 9.17.2
Published by tylim88 over 1 year ago
This patch consist of 2 important changes and 1 important fix:
WriteMerge
type, dedicated type for set merge operationDeleteField
type transformationthe old DeleteField is incorrectly being treated as object and will be replaced by error message when we union it with another object
in 2.4.7, DeleteField
is no longer treated as object
this is not a breaking change, it opens up a new possibility
DeleteField
Type Transformationtype ErrorUnionInvolveObjectType =
'Error: Please check your type declaration, do not union object literal type with other type except PossiblyReadAsUndefined'
type A = MetaTypeCreator<
{
b: {
d: { e: false } | DeleteField
}
},
'A'
>
type Read = {
b: {
d: ErrorUnionInvolveObjectType
}
}
type Write = {
b: {
d: ErrorUnionInvolveObjectType
}
}
type WriteFlatten = {
b: {
d: ErrorUnionInvolveObjectType
}
'b.d': ErrorUnionInvolveObjectType
}
type Compare = {
b: {
d: ErrorUnionInvolveObjectType
}
'b.d': ErrorUnionInvolveObjectType
}
DeleteField
Type Transformation:type A = MetaTypeCreator<
{
b: {
d: { e: false } | DeleteField
}
},
'A'
>
type Read = {
b: {
d: { e: false } | undefined
}
}
type Write = {
b: {
d: { e: false }
}
}
type WriteMerge = { // new type!
b: {
d: { e: false } | DeleteField
}
}
type WriteFlatten = {
b: {
d: { e: false } | DeleteField
'd.e': false
}
'b.d': { e: false } | DeleteField
'b.d.e': false
}
type Compare = {
b: {
d: { e: false }
'd.e': false
}
'b.d': { e: false }
'b.d.e': false
}
Published by tylim88 over 1 year ago
where
and limit
clause implement TS 5.0 const type parameters
npm i -D typescript@5
strongly recommend upgrade to v2.4 to enjoy performance improvement from TS v5