apollo-link-firebase provides you a simple way to query Firebase in graphQL with Apollo-client without building a graphQL server
Currently, we support features below:
- Query: All sorting and filtering methods on document are supported.
- Mutation: deal with
set
,update
,remove
methods with graphQL mutation. - Realtime Subscription: Listen to your Firebase events using graphQL Subscription.
- Data Join: Retrieve your data from different paths using one graphQL.
yarn add apollo-link-firebase
// rtdb stands for realtime database
import {createRtdbLink} from 'apollo-link-firebase';
import * as firebase from 'firebase';
// initialize firebase
firebase.initializeApp({
// configs
});
// create Realtime Database link
const rtdbLink = createRtdbLink({
database: firebase.database()
});
const client = new ApolloClient({
link: rtdbLink,
cache: new InMemoryCache(),
});
// A simple query to retrieve data from
// firebase.database().ref("/profile/me")
// @rtdbQuery stands for Realtime Database Query
const query = gql`
query myProfile {
me @rtdbQuery(ref: "/profile/me") {
name
}
}
`;
// Invoke the query and log the person's name
client.query({ query }).then(response => {
console.log(response.data.name);
});
In Apollo client, InMemoryCache
use __typename
and id
to save your data in store.
Using @key
directive, you can speficy which field you want to return with the key of snapshot
const query = gql`
query myProfile {
me @rtdbQuery(ref: "/profile/me", type: "Profile") {
id @key
name
}
}
`;
{
__typename: "Profile",
id: "me",
name: "wwwy3y3"
}
For example, your data in Firebase could be like
{
users: {
id1: {
name: "alovelace",
birth: 1815
},
id2: {
name: "ghopper",
birth: 1906
}
}
}
We can query all users, and use @array
directive to parse data to array
const query = gql`
query getUsers {
users @rtdbQuery(ref: "/users", type: "Users") @array {
id @key
name
}
}
`;
[{
__typename: "Users",
id: "id1",
name: "alovelace",
birth: 1815
}, {
__typename: "Users",
id: "id2",
name: "ghopper",
birth: 1906
}]
In firebase client js sdk, We can get data by using sorting and filtering API
We provide corresponding API in @rtdbQuery
directive arguments. In the following example, we query lists of data using orderByChild("birth")
and limitToFirst(1)
const query = gql`
query getUsers {
users @rtdbQuery(ref: "/users", orderByChild: "birth", limitToFirst: 1, type: "Users") {
name
}
}
`;
[{
__typename: "Users",
id: "id1",
name: "alovelace",
birth: 1815
}]
ref
: stringorderByChild
: stringorderByKey
: boolean. e,gorderByKey: true
orderByValue
: booleanstartAt
: anyendAt
: anyequalTo
: anylimitToFirst
: numberlimitToLast
: number
- Basic API Usage (orderBy*, limitTo*...)
- Advanced API Usage (nested array, data join...)
We only take payload from input
key from the recommendations in this article
const mutation = gql`
fragment Input on firebase {
string: String
number: Number
}
mutation($ref: string, $input: Input!) {
updateArticle(input: $input) @rtdbUpdate(ref: $ref, type: "Article") {
id @key
string
number
}
}
`;
We support four directives for mutation
@rtdbUpdate
: Firebase update@rtdbSet
: Firebase set@rtdbRemove
: Firebase remove@rtdbPush
: Push new element under ref, sugar api for firebase push and set
const mutation = gql`
mutation($ref: string) {
remove @rtdbRemove(ref: $ref)
}
`;
const mutation = gql`
fragment ProfileInput on firebase {
string: String
number: Number
}
mutation($ref: string, $input: ProfileInput!) {
pushdata(input: $input) @rtdbPush(ref: $ref) {
id @pushKey
string
number
}
}
`;
// variables
const variables = {
ref: "/users",
input: {
string: "string",
number: 1
}
}
// response
{
id: "-KjCIvxsKueb3Hf2LIOp",
string: "string",
number: 1
}
We support four events in Firebase, more on Firebase document
You can use all the query api supported in @rtdbQuery
, more advanced query examples in wiki
const subQuery = gql`
subscription {
newComment @rtdbSub(ref: "/comments", event: "value") {
id @key
content
}
}
`;
value
:@rtdbSub(ref: string, event: "value")
child_added
:@rtdbSub(ref: string, event: "child_added")
child_changed
:@rtdbSub(ref: string, event: "child_changed")
child_removed
:@rtdbSub(ref: string, event: "child_removed")
Here's a simple React + apollo-link-firebase todo app
- support firebase transaction
- support firestore
- support authenticate mutation
- support storage mutation
Contributions are welcome and extremely helpful 🙌
Feel free to join our gitter channel to discuss with us!