Welcome to "TWIL," our series designed to be your weekly dose of micro-learning. In this session, Marisa takes us through the interconnected world of Firebase: Firestore, Storage, and Cloud Functions. Learn how to build real-time apps with React-Native by using Firebase’s suite of tools to update Firestore documents with video paths from Cloud Storage asynchronously, all orchestrated via Cloud Functions. Lean in as we unveil the streamlined process of linking documents to media, a valuable snippet for developers looking to enhance functionality in real-time applications.
Firebase: Firestore, Storage and Cloud Functions 🤝
Use case
Say we have a document stored in Firestore. We upload a video to Cloud Storage, and we want to take the path of the video and add it to the document in Firestore. We can use Cloud Functions to accomplish this!
Video Data Document
{
scheduled: "September 18, 2019 at 10:30:00 AM UTC-4",
completed: "September 18, 2019 at 10:28:00 AM UTC-4",
file: "<cloud-storage-url>", // updated after video has finished uploading
}
Firestore
let documentID = ""
try {
// Get or Create a collection reference
const collectionRef = firestore().collection(
`company/${COMPANY_ID}/client/${CLIENT_ID}/videos`,
)
// Grab the docuemnt reference so that we can get the document id at the end of the path
const documentRef = await collectionRef.add(clientData) // `add` will auto-id this document for us
documentID = documentRef.path.split("/")[5]
console.log("*** Firestore reference created and uploaded at:", documentRef.path)
} catch (error) {
console.log("*** Firestore - error getting collection:", { error })
}
Cloud Storage
// Record a video and return the data for it
const data = await camera.recordAsync(options)
// Get the storage object reference at the specified path (we use the same path as the document in firestore)
const reference = storage().ref(
`company/${COMPANY_ID}/client/${CLIENT_ID}/videos/${documentID}.mov`,
)
console.log("*** Storage reference created at:", reference.fullPath)
// Put the video file at the reference path
reference.putFile(data.uri)
Cloud Function
const functions = require("firebase-functions")
const admin = require("firebase-admin")
admin.initializeApp()
const firestore = admin.firestore()
/**
* Triggered by a new object being created in Storage.
*
* - Check if the object is a video, if not, return.
* - If so, get the corresponding Firestore document reference for this video. The paths should match.
* - Update the document reference with the file path for the uploaded video.
*/
exports.updateDocument = functions.storage.object().onFinalize(async object => {
const { contentType } = object
const filePath = object.name
// Exit if this is triggered on a file that is not a video
if (!contentType.startsWith("video/")) {
return console.log("This is not a video.")
}
// Get document reference for this filePath
const documentRef = await firestore.doc(filePath.replace(".mov", ""))
// Update document with filepath for uploaded video
await documentRef.update({ file: filePath })
return true
})
- JavaScript
- React-Native
- Firebase
- Google Cloud Storage
- Google Cloud Functions
- Async