1. Tạo 1 project functions
firebase init functions
để kết nối với firebase project
2. Sử dụng busboy-firebase
để nhận files upload
const app = require('express')(); const bb = require('busboy-firebase'); const {functions, bucket} = require('../app'); const genId = require('cf-gen-id'); const {genDownloadUrlFromMetadata} = require( '../utils/genDownloadUrlFromMetadata'); const cors = require('cors'); app.use(cors()); app.post('/', bb, async (req, res) => { const downloadUrls = await Promise.all( //busboy-firebase xử lý với file nhận đc từ client và đưa vào req.files req.files?.map(async f => { const fname = f.originalname; const contents = f.buffer; await bucket.file(fname).save(contents); //lưu nội dung file // thêm metadata để có thể lấy link download từ storage const [meta] = await bucket.file(fname).setMetadata({ metadata: { firebaseStorageDownloadTokens: genId('token_', 20), }, }); //trả về link có thể download return genDownloadUrlFromMetadata(meta, fname); }), ); res.json({downloadUrls}); }); exports.upload = functions.https.onRequest(app);
Setting biến môi trường
CONSTANTS.js
const IS_CLI = process.env.IS_FIREBASE_CLI === 'true'; const STORAGE_EMULATOR_HOST = process.env.STORAGE_EMULATOR_HOST; const BUCKET_NAME = 'tên bucket trên firebase' // ví dụ `formzin-com.appspot.com` const FUNCTIONS_REGION = 'asia-southeast1'; //singpore module.exports = { IS_CLI, STORAGE_EMULATOR_HOST, BUCKET_NAME, FUNCTIONS_REGION, };
app.js
const {initializeApp} = require('firebase-admin/app'); const {getStorage} = require('firebase-admin/storage'); let functions = require('firebase-functions'); const {BUCKET_NAME, FUNCTIONS_REGION} = require('./CONSTANTS'); functions = functions.region(FUNCTIONS_REGION); const FB_CONFIG = JSON.parse(process.env.FIREBASE_CONFIG); const app = initializeApp({ ...FB_CONFIG, storageBucket: BUCKET_NAME, }); const storage = getStorage(app); const bucket = storage.bucket(); module.exports = exports = { app, storage, bucket, functions, };
genDownloadUrlFromMetadata.js
const {IS_CLI, STORAGE_EMULATOR_HOST, BUCKET_NAME} = require('../CONSTANTS'); const genDownloadUrlFromMetadata = (meta, fileName) => { const firebaseStorageDownloadTokens = meta?.metadata?.firebaseStorageDownloadTokens; let url; if (firebaseStorageDownloadTokens) { const domain = IS_CLI ? STORAGE_EMULATOR_HOST : 'https://firebasestorage.googleapis.com'; url = `${domain}/v0/b/${BUCKET_NAME}/o/${encodeURIComponent( fileName)}?alt=media&token=${firebaseStorageDownloadTokens}`; } else { url = meta?.mediaLink; } return url; }; exports.genDownloadUrlFromMetadata = genDownloadUrlFromMetadata;
Test local với firebase-emulators
firebase emulators:start --only functions,storage
Upload thử với Postman
Deploy functions
firebase deploy --only functions:upload
Open to the world
- Vào gcloud functions, thêm quyền allUser có thể invoke function
upload
vừa deploy
Test lại với Postman
Done 🤗
Chúc các bạn thành công 🍻🍺