1. Tạo 1 project functions
firebase init functions
để kết nối với firebase project
![Ảnh chụp Màn hình 2022-03-09 lúc 11.30.31.png](https://firebasestorage.googleapis.com/v0/b/classfunc-com.appspot.com/o/blogs%2Falbums%2Fuppy-a%2Fnh%2Fchu%2Fp%2Fma%2Fn%2Fhi%2Fnh%2F2022%2F03%2F09%2Flu%2Fc%2F11%2F30%2F31%2Fpng-o9-10-p3-10-o0-10-o0-10-1d-1d-10-o1-10-1e-1e-1e-image%2Fpng-115428-1646800237152_A%CC%89nh%20chu%CC%A3p%20Ma%CC%80n%20hi%CC%80nh%202022-03-09%20lu%CC%81c%2011.30.31.png?alt=media&token=ec7a9b7a-26b9-4792-8618-0247e94ade03)
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
![Ảnh chụp Màn hình 2022-03-09 lúc 12.46.45.png](https://firebasestorage.googleapis.com/v0/b/classfunc-com.appspot.com/o/blogs%2Falbums%2Fuppy-a%2Fnh%2Fchu%2Fp%2Fma%2Fn%2Fhi%2Fnh%2F2022%2F03%2F09%2Flu%2Fc%2F12%2F46%2F45%2Fpng-o9-10-p3-10-o0-10-o0-10-1d-1d-10-o1-10-1e-1e-1e-image%2Fpng-174747-1646804811237_A%CC%89nh%20chu%CC%A3p%20Ma%CC%80n%20hi%CC%80nh%202022-03-09%20lu%CC%81c%2012.46.45.png?alt=media&token=a95b740d-5629-46c6-86c4-f5d0d9ef4f86)
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
![Ảnh chụp Màn hình 2022-03-09 lúc 12.51.27.png](https://firebasestorage.googleapis.com/v0/b/classfunc-com.appspot.com/o/blogs%2Falbums%2Fuppy-a%2Fnh%2Fchu%2Fp%2Fma%2Fn%2Fhi%2Fnh%2F2022%2F03%2F09%2Flu%2Fc%2F12%2F51%2F27%2Fpng-o9-10-p3-10-o0-10-o0-10-1d-1d-10-o1-10-1e-1e-1e-image%2Fpng-212995-1646805092699_A%CC%89nh%20chu%CC%A3p%20Ma%CC%80n%20hi%CC%80nh%202022-03-09%20lu%CC%81c%2012.51.27.png?alt=media&token=5d4d4ac3-8df9-4560-be92-9f97b67fcb50)
![Ảnh chụp Màn hình 2022-03-09 lúc 12.51.14.png](https://firebasestorage.googleapis.com/v0/b/classfunc-com.appspot.com/o/blogs%2Falbums%2Fuppy-a%2Fnh%2Fchu%2Fp%2Fma%2Fn%2Fhi%2Fnh%2F2022%2F03%2F09%2Flu%2Fc%2F12%2F51%2F14%2Fpng-o9-10-p3-10-o0-10-o0-10-1d-1d-10-o1-10-1e-1e-1e-image%2Fpng-175021-1646805080170_A%CC%89nh%20chu%CC%A3p%20Ma%CC%80n%20hi%CC%80nh%202022-03-09%20lu%CC%81c%2012.51.14.png?alt=media&token=8cb4c285-5cff-4331-b9e0-bdf5c0a6f946)
Test lại với Postman
![Ảnh chụp Màn hình 2022-03-09 lúc 12.53.56.png](https://firebasestorage.googleapis.com/v0/b/classfunc-com.appspot.com/o/blogs%2Falbums%2Fuppy-a%2Fnh%2Fchu%2Fp%2Fma%2Fn%2Fhi%2Fnh%2F2022%2F03%2F09%2Flu%2Fc%2F12%2F53%2F56%2Fpng-o9-10-p3-10-o0-10-o0-10-1d-1d-10-o1-10-1e-1e-1e-image%2Fpng-207947-1646805242044_A%CC%89nh%20chu%CC%A3p%20Ma%CC%80n%20hi%CC%80nh%202022-03-09%20lu%CC%81c%2012.53.56.png?alt=media&token=09388077-e130-4dea-8996-1ef2d6d1306e)
Done 🤗
Chúc các bạn thành công 🍻🍺