Accessing Google Firestore on Vercel
Or on any other cloud service, or language.
TL;DR: Use GOOGLE_APPLICATION_CREDENTIALS with a valid JSON credential to use any Google APIs anywhere.
Firebase Hosting is great, but the new Vercel is awesome for NextJS apps. On Vercel your code runs on Lambda@Edge and it is cached on CloudFront; in the same way, Firebase uses Fastly, another great CDN.
You can not take full advantage of running a NextJS app on Firebase Hosting, only on Vercel, or by deploying manually.
I like to use Firestore on some projects, and unfortunately it is “restricted” to the internal network of Google Cloud, although there is a trick; you can download the service account and export an environment variable named GOOGLE_APPLICATION_CREDENTIALS
with the path of the downloaded credential.
First, download the JSON file following this steps.
Then, convert the credentials JSON file to base64:
base64 < credentials.json
Now copy the result and create an environment variable on Vercel named GOOGLE_CREDENTIALS
and paste the contents.
On your NextJS project, create a pages/api/function.js
and add the following code:
import os from "os"
import { promises as fsp } from "fs"
import path from "path"
import { Firestore, FieldValue } from "@google-cloud/firestore"
let _firestore = null
const lazyFirestore = () => {
if (!_firestore) {
const baseDir = await fsp.mkdtemp((await fsp.realpath(os.tmpdir())) + path.sep)
const fileName = path.join(baseDir, "credentials.json")
const buffer = Buffer.from(process.env.GOOGLE_CREDENTIALS, "base64")
await fsp.writeFile(fileName, buffer)
process.env["GOOGLE_APPLICATION_CREDENTIALS"] = fileName
_firestore = new Firestore()
}
return _firestore
}
export default async (req, res) => {
const firestore = await lazyFirestore()
const increment = FieldValue.increment(1)
const documentRef = firestore.collection("v1").doc("default")
await documentRef.update({ counter: increment })
res.status(200).json({})
}
Done! Now it is possible to use Firestore on Vercel or anywhere.