You can either write queries inside your JavaScript files with gql
, or if you use webpack, you can use graphql-tag/loader
to import GraphQL query files (*.graphql
) directly.
Collections
Every top-level name in a query
is considered a Firestore collection. For
example, in the query below, we are querying every document in the posts
collection and retrieving the id
, title
, and body
values from each
document in the response. Note: id
is a special field that actually retrieves
the document key.
const { posts } = await firegraph.resolve(
firestore,
gql`
query {
posts {
id
title
body
}
}
`
);
Subcollections
When you have nested values (e.g. in the query below), they are processed
as child collections. To clarify, for each doc
in the posts
collection,
we also retrieve the posts/${doc.id}/comments
collection. This result is
stored in the comments
key for each document that is returned.
const { posts: postsWithComments } = await firegraph.resolve(
firestore,
gql`
query {
posts {
id
title
body
comments {
id
body
}
}
}
`
);
Document References
If post.author
is a DocumentReference
field, it is considered as a complete path to the document from the root of the database.
If post.author
is a String
type of field, it is also considered as a complete path to document. However, you can optionally provide a parent path to the document collection using the path
argument. Note that path argument must end in a "/"
to be valid.
const { posts: postsWithAuthorAndComments } = await firegraph.resolve(
firestore,
gql`
query {
posts {
id
title
body
# Here author is either a DocumentReference type of field
# or is a String field with complete path to the document
author {
id
displayName
}
comments {
id
body
# Here author's id is only saved in the field,
# hence parent path to document is provided
authorId(path: "users/") {
id
displayName
}
}
}
}
`
);
Filtering Results
One of our primary goals is to wrap the Firestore API in its entirety. That said, the where
clause in Firegraph maps directly to the expected behavior in Firestore:
someKey: someValue
maps to .where(someKey, '==', someValue)
someKey_gt: someValue
maps to .where(someKey, '>', someValue)
someKey_gte: someValue
maps to .where(someKey, '>=', someValue)
someKey_lt: someValue
maps to .where(someKey, '<', someValue)
someKey_lte: someValue
maps to .where(someKey, '>=', someValue)
someKey_contains: someValue
maps to .where(someKey, 'array-contains', someValue)
For the last one, of course, someKey
would have to use Firestore's array type. All of the restrictions
related to compound queries with Firestore (no logical OR or inequality testing) still apply but those
are some of the first things we are hoping to add support for.
const authorId = 'sZOgUC33ijsGSzX17ybT';
const { posts: postsBySomeAuthor } = await firegraph.resolve(
firestore,
gql`
query {
posts(where: {
author: ${authorId},
}) {
id
message
author {
id
displayName
}
}
}
`
);
Ordering Results
The result of sub/collections can be ordered by using the orderBy
clause, with providing an object containing fields and their order type of either asc
ending or desc
ending
const { posts } = await firegraph.resolve(
firestore,
gql`
query {
posts(orderBy: { createdOn: "desc", title: "asc" }) {
id
title
createdOn
body
}
}
`
);
NOTE: The indexes
for ordering fields must be created beforehand in firebase console, and those fields should be part of the query.
Limiting Results
To limit the loading of documents to a certain number in a sub/collection query, limit
argument can be supplied to the query.
const { posts } = await firegraph.resolve(
firestore,
gql`
query {
posts(limit: 10) {
id
title
body
comments(limit: 10) {
id
message
}
}
}
`
);
Roadmap
- [x] Querying values from collections
- [x] Querying nested collections
- [ ] GraphQL mutations allowing updates to multiple documents at once
- [ ] Basic search functionality (on par with current Firestore API)
- [ ] More advanced search functionality (GraphQL params, fragments, etc)
Contributing
Thank you for your interest! You are welcome (and encouraged) to submit Issues and Pull Requests. If you want to add features, check out the roadmap above (which will have more information as time passes). You are welcome to ping me on Twitter as well: @sjroot