Alex Patterson
Posted on May 1, 2020
Backup Sanity with Cloud Firestore
New Firebase Project
In order to accept webhooks from Sanity you will need to have a firebase project setup, you can search this site for many examples. But most simply run firebase init
on your command line and select Functions and Firestore, you can keep all other defaults.
After selecting an existing or creating a new project make sure to select TypeScript
Cloud Firestore
If you run into any issues on the command line, you can open the console and validate your Firestore database has been created.
The main thing that needs to happen in firestore is to make sure that your rules will allow you to write to the database. Make sure in firestore.rules, you have something similar to this based on the content that you are bringing over. Realisticly we are using the the admin functions so you don't need these rules to write, but it is nice to remember if you are getting blocked in your site for read access.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /sanity/{sanityId} {
allow read: if true;
allow write: if false;
match /courses/{courseId} {
allow read: if true;
allow write: if false;
}
match /sections/{sectionId} {
allow read: if true;
allow write: if false;
}
match /modules/{moduleId} {
allow read: if true;
allow write: if false;
}
}
}
}
Firebase Cloud Function WebHook
Within the directory functions->src_index.ts
you can now update this file with the below code. Making sure to replace 'YOURKEY'
with the key from your sanity project id found in settings.
import * as admin from 'firebase-admin';
admin.initializeApp();
import * as functions from 'firebase-functions';
export const db = admin.firestore();
const settings = { timestampsInSnapshots: true };
db.settings(settings);
const fetch = require('node-fetch');
export const sanityWebhookHandler = functions.https.onRequest(async (req, res) => {
if (req.body.projectId !== 'YOURKEY') {
res.status(500).send();
}
try {
console.log(JSON.stringify(req.body));
await getSanityData(req.body);
res.status(200).send();
} catch (err) {
console.log(JSON.stringify(err));
res.status(400).send(err);
}
}
);
const getSanityData = async (body) => {
console.log('Setting up client', body.projectId, );
for(const id of body.ids.all){
const url = `https://${body.projectId}.api.sanity.io/v1/data/query/${body.dataset}?query=*[_id%20==%20$id]&$id=%22${id}%22`;
console.log(url);
const resp = await (await fetch(url)).json();
const {result} = resp;
for(const item of result){
console.log('Updating', `${item._type}/${item._id}`);
await db.doc(`sanity/docs/${item._type}/${item._id}`).set(item, { merge: true });
}
}
}
Once this is complete you can run command firebase deploy
.
You can then go to the Firebase Console and copy your url, you will need this later for the sanity webhook url.
Sanity Setup
https://www.sanity.io/docs/webhooks
In your Sanity Console you can edit webhooks in your settings https://manage.sanity.io/projects/<your-projectid>/settings/api
You can then add your Firebase Cloud Function URL and select the dataset you would like to get updates from.
Now anytime you make a change in your
Sanity Pro Tip
If you already have data in Sanity and would like to trigger all of your documents to update you can export and then import your entire dataset. Run the below commands inside of a project running sanity.
sanity dataset export something.tar.gz
sanity dataset import something.tar.gz --replace
Posted on May 1, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.