I'm combining a GraphQL app with my existing Firebase project and am having a lot of problems getting the queries to correctly get data from the firestore().
So far I have the mutations working correctly, but when I go to query the data I can't get the firestore().get() snapshot into a form that graphQL will recognize.
so far it looks like this:
const {GraphQLObjectType,
GraphQLString,
GraphQLBoolean,
GraphQLFloat,
GraphQLSchema,
GraphQLID,
GraphQLList,
GraphQLNonNull} = require("graphql");
const admin = require('firebase-admin');
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
//Models
const Room = admin.firestore().collection('room');
const Position = admin.firestore().collection('position');
const Plant = admin.firestore().collection('plant');
const PlantInfo = admin.firestore().collection('plantInfo');
const RoomType = new GraphQLObjectType({
name: "Room",
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
description: { type: GraphQLString },
floor: { type: GraphQLString },
building: { type: GraphQLString },
positions: {
type: new GraphQLList(PositionType),
resolve(parent, arg) {
//return _.filter(positions, {inRoomId:parent.id})
return Position.orderByChild('inRoomId').equalTo(parent.id);
}
}
})
});
const PositionType = new GraphQLObjectType({
name: "Position",
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
description: { type: GraphQLString },
exposure: { type: GraphQLString },
size: { type: GraphQLString },
inRoom: {
type: RoomType,
resolve(parent, args) {
//return _.find(rooms, {id:parent.inRoomId})
return Room.child(parent.inRoomId);
}
}
})
});
const RootQuery = new GraphQLObjectType({
name: "RootQueryType",
fields: {
room: {
type: RoomType,
args: { id: { type: GraphQLID } },
resolve(parent, args) {
//code to get data from db/othersourse
//return _.find(rooms, {id: args.id});
return Room.child(args.id);
}
},
position: {
type: PositionType,
args: { id: { type: GraphQLID } },
resolve(parent, args) {
//code to get data from db/othersourse
//return _.find(positions, {id: args.id})
return Position.child(args.id);
}
},
rooms: {
type: new GraphQLList(RoomType),
resolve(parent, args) {
//return rooms
return Room.get().then(snapshot => {snapshot.forEach(doc => {return doc})})
}
},
positions: {
type: new GraphQLList(PositionType),
resolve(parent, args) {
//return positions
return Position.get().then(doc => console.log(doc)).catch(err => console.log('Error getting document', err));
}
}
}
});
const Mutation = new GraphQLObjectType({
name: "Mutation",
fields: {
addRoom: {
type: RoomType,
args: {
name: { type: new GraphQLNonNull(GraphQLString) },
floor: { type: new GraphQLNonNull(GraphQLString) },
building: { type: new GraphQLNonNull(GraphQLString) }
},
resolve(parent, args) {
let room = {
name: args.name,
floor: args.floor,
building: args.building
};
return Room.add(room);
}
},
addPosition: {
type: PositionType,
args: {
name: { type: new GraphQLNonNull(GraphQLString) },
exposure: { type: new GraphQLNonNull(GraphQLString) },
size: { type: new GraphQLNonNull(GraphQLString) },
inRoomId: { type: new GraphQLNonNull(GraphQLString) }
},
resolve(parent, args) {
let position = {
name: args.name,
exposure: args.exposure,
size: args.size,
inRoomId: args.inRoomId
};
return Position.add(position);
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery,
mutation: Mutation
});
Under the RootQuery -> Rooms I'm trying to get a graphQL query to return all the rooms in my 'room' collection. I have been able to get it to console.log() a list of documents using:
return Room.get()
.then(snapshot => {
snapshot.forEach(doc => {
console.log(doc.id, " => ", doc.data());
But getting this into an array has so far eluded me. Any help is really appreciated.
Seeing as no one was able to answer this, I ended up figuring it out for myself :p
So resolve functions relating to getting a collection of related data for example positions. the following works:
first you need a function to convert the snapshots into an array as this is what graphQL is expecting. This also allows your to seperate the id and add it in with the array item:
Next when getting the data you use .get() which returns a promise (and error) which can be passed into the snapshotToArray().
For resolve functions that only call on one dataset for example inRoom. Its similar to the first one except using .where() and seperating the id and data() in the snapshot functions:
Just incase someone else runs into the same problem :)