- vừa được xem lúc

Upload files lên Firebase Cloud Storage với Vue.js và Node.js

0 0 25

Người đăng: Pham Tuan Viet

Theo Viblo Asia

File uploads là một phần quan trọng trong ứng dụng web ngày này. Trong bài viết này, chúng ta sẽ cùng nhau xây dựng một function upload file nho nhỏ và đẩy lên Firebase Cloud Storage với sự kết hợp giữa Vue và Node.js.

Set up Firebase project

Đầu tiên, chúng ta cần có một tài khoản firebase (chúng ta có thể đăng ký tại đây). Truy cập https://console.firebase.google.com/ và tạo một project mới. Chọn Storage và lựa chọn location để tạo bucket mặc định.

Bây giờ, chúng ta cần kết nối với bucket bằng cách tạo ra một private key để bảo vệ kết nối. Trong project settings, click vào tab Service Accounts và click nút "Generate private key". Sau đó Firebase sẽ sinh ra một JSON file bao gồm credentials của tài khoản firebase.

Node.js API

Init node.js api

Để upload files chúng ta sẽ sử dụng package multerfirebase-admin.

npm i express multer firebase-admin

Tiếp theo chúng ta cần tạo một index.js webserver và import các dependencies.

const express = require('express')
const multer = require('multer')
const app = express()
app.use(express.urlencoded({extended: false}))
app.use(express.json({extended: false}))
app.post('/upload', (req, res) => { console.log("File upload API")
}) app.listen(3001, () => { console.log('?Server listening on port 3001')
})

Chúng ta xây dựng file upload API sử dụng multer cho việc upload file. Multer cung cấp req.file object bao gồm thông tin files và req.body bao gồm các trường dữ liệu. Chúng ta sẽ sử dụng MemoryStorage được cung cấp bởi multer.

const upload = multer({ storage: multer.memoryStorage()
})
app.use(upload.single())

Bây giờ chúng ta có thể truy cập thông tin file với req.file. Nếu muốn upload multiple files sử dụng upload.any() thay thế cho upload.single() và truy cập thông tin file với req.files.

index.js file:

const express = require('express')
const multer = require('multer')
const app = express()
app.use(express.urlencoded({extended: false}))
app.use(express.json({extended: false})) const upload = multer({ storage: multer.memoryStorage()
}) app.post('/upload', upload.single('file'), (req, res) => { console.log("File upload API")
} app.listen(3001, () => { console.log('?Server listening on port 3001')
})

Connect to firebase

Chúng ta sẽ cần kết nối tới Firebase bằng cách tạo firebase.js để import firebase package và khởi tạo firebase admin SDK.

firebase.js

const admin = require('firebase-admin') // Initialize firebase admin SDK
admin.initializeApp({ credential: admin.credential.cert(<path to your firebase credentials file>), storageBucket: <firebaseprojectid>.appspot.com
})
// Cloud storage
const bucket = admin.storage().bucket() module.exports = { bucket
}

Upload files to firebase

Tiếp theo, chúng ta cần import bucket firebase.js đã khởi tạo ở trên vào index.js.

const firebase = require('./firebase')

Đầu tiên khi thực hiện upload file, chúng ta cần kiểm tra request thực sự tồn tại file tải lên hay không. Nếu request không tồn tại chúng ta sẽ trả về mã lỗi 400.

if(!req.file) { res.status(400).send("Error: No files found")
}

Firebase sử dụng blobs để lưa trữ dữ liệu mã nhị phân (binary data). blobs hay Binary Large Objects, là một tập hợp mã nhị phân được lưu trữ dưới dạng một thực thể (entity) trong database. Chúng ta có thể tạo một blob sử dụng bucket.file() với tên file upload.

const blob = firebase.bucket.file(req.file.filename)

Bây giờ, chúng ta cần tạo một luồng ghi dữ liệu (writable stream) trực tiếp để xử lý dữ liệu đến. Streams về cơ bản là tập hợp dữ liệu, nhưng nó không có sẵn cùng một lúc mà chúng ta cần xử lý từng đoạn một.

Chúng ta cần chuyển mimetype của tệp dưới dạng metadata nếu không chúng ta không thể đọc được dữ liệu với định dạng thích hợp.

cosnt blobWriter = blob.createWriteStream({ metadata: { contentType: req.file.mimetype }
})

Chúng ta cần kiểm tra lỗi trong khi tạo luồng ghi dữ liệu bới sự kiện error trong blobWriter

blobWriter.on('error', (err) => { console.log(err)
})

Khi upload file thành công chúng tầ trả dữ liệu tới client với sự kiện finish

blobWriter.on('finish', () => { res.status(200).send("File uploaded.")
})

Và khi dữ liệu được xử lý hoàn toàn sự kiện end sẽ được gọi

blobWriter.end(req.file.buffer)

Như vậy chúng ta đã tạo xong Node.js API để upload files lên Firebase Cloud Storage.

index.js

const express = require('express')
const multer = require('multer')
const firebase = require('./firebase')
const app = express() app.use(express.urlencoded({extended: false}))
app.use(express.json({extended: false})) const upload = multer({ storage: multer.memoryStorage()
}) app.post('/upload', upload.single('file'), (req, res) => { if(!req.file) { return res.status(400).send("Error: No files found") } const blob = firebase.bucket.file(req.file.originalname) const blobWriter = blob.createWriteStream({ metadata: { contentType: req.file.mimetype } }) blobWriter.on('error', (err) => { console.log(err) }) blobWriter.on('finish', () => { res.status(200).send("File uploaded.") }) blobWriter.end(req.file.buffer)
}) app.listen(3001, () => { console.log('?Server listening on port 3001')
})

Frontend với Vue.js

Chúng ta sẽ tạo frontend để thực hiện upload file với Vue.js. Tạo một input filed và một button để gọi tới API.

<input type="file" ref="file" v-on:change="handleUpload()"/>
<button v-on:click="uploadFile()">Upload</button>

Tiếp đó, cần thêm function handleUpload để kích hoạt khi người dùng chọn tệp tin. Khi người dùng chọn file handleUpload sẽ kích hoạt và input file sẽ được lưu vào biến.

<script> export default { data() { return { file: '' } }, methods: { handleFileUpload(){ this.file = this.$refs.file.files[0] }, uploadFile(){ } } }
</script>

Sử dụng FormData để tạo object chưa thông tin file và append file và formData.

const formData = new FormData()
formData.append("file", this.file)

Tên file phía backend API upload.single(<field name>) phải giống với tên file trong formData.

Cuối cùng, chúng ta có thể send file tới API với Axios để post dữ liệu.

axios.post('http://localhost:3001/upload', formData, { headers: { "Content-Type": "multipart/form-data" }
}).then(response => { console.log(response.data)
}).catch(error => { console.log(error)
})

File vue.js cuối cùng:

<template> <div id="app"> <input type="file" ref="file" v-on:change="handleUpload()"/> <button v-on:click="uploadFile()">Upload</button> <br> </div>
</template> <script>
import axios from 'axios'
export default { data () { return { file: '' } }, methods: { handleUpload() { this.file = this.$refs.file.files[0] }, uploadFile() { const formData = new FormData() formData.append("file", this.file) axios.post('http://localhost:3001/upload', formData, { headers: { "Content-Type": "multipart/form-data" } }).then(response => { console.log(response.data) }).catch(error => { console.log(error) }) } }
}
</script>

Như vậy, chúng ta đã tạo thành công một ứng dụng upload file với Node.js và Vue.js tới Firebase.

Chúng ta có thể lấy full code project tại đây

Nếu bạn có bất kỳ nghi ngờ nào hoặc cần làm rõ thêm, hãy cho tôi biết trong phần bình luận. Tôi rất vui được giúp bạn. Nếu bạn thấy bài viết này hữu ích hoặc thú vị, hãy xem xét giành tặng 1 upvote nhé.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

0 0 376

- vừa được xem lúc

Hướng dẫn làm bot Facebook messenger cho tài khoản cá nhân

Giới thiệu. Trong bài viết trước thì mình có hướng dẫn các bạn làm chatbot facebook messenger cho fanpage. Hôm nay mình sẽ hướng dẫn các bạn tạo chatbot cho một tài khoản facebook cá nhân. Chuẩn bị.

0 0 152

- vừa được xem lúc

Crawl website sử dụng Node.js và Puppeteer - phần 2

trong phần 1 mình đã giới thiệu về puppeteer và tạo được 1 project cùng một số file đầu tiên để các bạn có thể crawl dữ liệu từ một trang web bất kỳ. Bài này mình sẽ tiếp nối bài viết trước để hoàn thiện seri này.

0 0 59

- vừa được xem lúc

Điều React luôn giữ kín trong tim

■ Mở đầu. Ngồi viết bài khi đang nghĩ vu vơ chuyện con gà hay quả trứng có trước, mình phân vân chưa biết sẽ chọn chủ đề gì để chúng ta có thể cùng nhau bàn luận.

0 0 44

- vừa được xem lúc

Gửi Mail với Nodejs và AWS SES

AWS SES. AWS SES là gì.

0 0 72

- vừa được xem lúc

Crawl website sử dụng Node.js và Puppeteer - phần 1

Bài viết này mình sẽ giới thiệu cho các bạn craw dữ liệu của web site sử dụng nodejs và Puppeteer. .

0 0 150