Skip to content

Instantly share code, notes, and snippets.

@erfg12
Last active May 30, 2021 21:27
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 erfg12/f5a6ef802f2883ae9327ae7d2fdaaee0 to your computer and use it in GitHub Desktop.
Save erfg12/f5a6ef802f2883ae9327ae7d2fdaaee0 to your computer and use it in GitHub Desktop.
Firebase forum system functions.
// ABOUT: These are functions for a Firebase forum system.
// You need NodeJS (nodejs.org) installed on your dev PC and create an Algolia and firebase project.
// Create an empty folder.
// Open terminal/cmd, navigate to the new folder and type in (NOTE: Use TypeScript):
// npm install -g firebase-tools
// firebase login
// firebase init
// npm install algoliasearch --save
// firebase functions:config:set algolia.appid="YOUR_APP_ID" algolia.apikey="YOUR_API_KEY"
// Open 'functions/src/index.ts' with a text editor like NotePad and put this code in it.
// After, in terminal/cmd type in 'firebase deploy' to make it go live. (This process can be kinda slow at times.)
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import algoliasearch from 'algoliasearch';
// CONFIGURATION
const algoliaIndex = "ALGOLIA_INDEX_NAME_HERE";
// END
admin.initializeApp();
const db = admin.firestore();
const algoliaClient = algoliasearch(functions.config().algolia.appid, functions.config().algolia.apikey);
const collectionIndex = algoliaClient.initIndex(algoliaIndex);
// HTTP request, show list of all users
export const getUserList = functions.https.onRequest(async (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'GET');
res.set('Access-Control-Allow-Headers', '*');
const listAllUsers = (nextPageToken?: any) => { // List batch of users, 1000 at a time.
admin
.auth()
.listUsers(1000, nextPageToken)
.then((listUsersResult) => {
// our JSON structure
type User = {
displayName: string | undefined;
photoURL: string | undefined;
};
let TheRecord: { [uid: string]: User } = {};
// iterate through users from server
listUsersResult.users.forEach((userRecord) => {
// build JSON data with key UID.
TheRecord[userRecord.uid] = {
displayName: userRecord.displayName,
photoURL: userRecord.photoURL,
};
});
if (listUsersResult.pageToken) { // List next batch of users.
res.status(200).send(listAllUsers(listUsersResult.pageToken));
} else {
res.send(TheRecord);
}
})
.catch((error) => {
console.log('Error listing users:', error);
});
};
listAllUsers();
});
// Send post data to Firestore (new post and replies)
export const newPost = functions.https.onRequest(async (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'POST');
res.set('Access-Control-Allow-Headers', '*');
var DBCollection = "topics";
if (req.method === 'POST') {
var data = {
category: req.body.category,
content: req.body.content,
title: req.body.title,
user_id: req.body.accid,
created: Number(Date.now().toString())
};
if (req.body.type === "reply")
DBCollection = "replies";
db.collection(DBCollection).add(data)
.then(function(docRef) {
res.setHeader('Content-Type', 'application/json');
res.status(200).json({message: "success", id: docRef.id});
});
}
});
// Automatic request on new docs in firestore to update Algolia indices
export const algoliaTopicsSync = functions.firestore.document('topics/{docId}').onWrite((change, _context) => {
const oldData = change.before;
const newData = change.after;
const data = newData.data();
const objectID = newData.id;
if (!oldData.exists && newData.exists) { // creating
return collectionIndex.saveObject(Object.assign({}, { objectID }, data));
} else if (!newData.exists && oldData.exists) { // deleting
return collectionIndex.deleteObject(objectID);
} else { // updating
return collectionIndex.saveObject(Object.assign({}, { objectID }, data));
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment