Skip to content

Instantly share code, notes, and snippets.

@pberden
Last active March 14, 2018 08:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pberden/5fc2f574390f25a0f34c0e00bf19de38 to your computer and use it in GitHub Desktop.
Save pberden/5fc2f574390f25a0f34c0e00bf19de38 to your computer and use it in GitHub Desktop.
Cloud Function - copy questions
import { IPlayer } from "./models";
export function getPlayerList(numberOfPlayers: number): IPlayer[] {
return Array.from(
Array(numberOfPlayers),
(_, i) => ({
order: i,
email: '',
score: 0
})
);
}
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as helper from './generate-helper';
import { IGame, IQuestion, IPlayer } from './models';
admin.initializeApp(functions.config().firebase);
async function getQuestions(db: admin.firestore.Firestore, quizId: string): Promise<IQuestion[]> {
const questions = await db.collection('quizes')
.doc(quizId)
.collection('questions')
.get();
const response = [];
questions.forEach((doc) => response.push(doc.data()));
return response;
}
async function addPlayer(db: admin.firestore.Firestore, gameId: string, player: IPlayer): Promise<FirebaseFirestore.DocumentReference> {
const playerRef = await db.collection('games')
.doc(gameId)
.collection('players')
.add(player);
return playerRef;
}
async function addQuestions(playerRef:FirebaseFirestore.DocumentReference, questions: IQuestion[]): Promise<any> {
const promises = [];
questions.forEach(question => {
promises.push(
playerRef.collection('questions')
.add(question)
)
})
return Promise.all(promises);
}
export const generate = functions.https.onRequest(async (req, res) => {
try {
const game: IGame = req.body;
const db = admin.firestore();
// 1 Get questions
const questions = await getQuestions(db, game.quizId);
// 2 Create player list
const players = helper.getPlayerList(game.numberOfPlayers);
// 3 Add players
const addingPlayers = players.map(async player => {
const yolo = await addPlayer(db, game.id, player);
return yolo;
});
const addingQuestions = await addingPlayers.map(playerRef => addQuestions(playerRef, questions))
// 4. Wait for all players to be added
const response = await Promise.all(addPlayers);
// Return response
res.json(response);
}
catch (err) {
console.error('Failed to generate game:', err);
res.status(504).json(err);
}
})
distribute.getQuestions(db, game).mergeMap(
questions => Rx.Observable.from(players),
(questions, player) => {
return { questions, player };
}
).mergeMap(
data => distribute.addPlayer(db, game, data.player),
(data, player) => {
return {
'questions': data.questions,
'player': data.player,
'playerRef': player
};
}
).mergeMap(
data => distribute.addQuestions(data.playerRef, data.player, data.questions, game.numberOfPlayers),
(data, question) => {
return { player: data.player };
}
)
// Reduce results and report back to client
.reduce((acc, cur) => {
acc.push(cur);
return acc;
}, [])
.subscribe(
(result) => res.json(result),
(error) => errorHandler(error)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment