ลงสนามด้วย Vue.js และ Firestore
เผยแพร่แล้ว: 2022-03-10Google Firebase มีความเป็นไปได้ในการจัดเก็บข้อมูลแบบใหม่ที่เรียกว่า 'Firestore' (ปัจจุบันอยู่ในช่วงเบต้า) ซึ่งต่อยอดจากความสำเร็จของ Firebase Realtime Database แต่ได้เพิ่มคุณลักษณะที่ดีบางอย่างเข้าไป ในบทความนี้ เราจะตั้งค่าพื้นฐานของเว็บแอปโดยใช้ Vue.js และ Firestore
สมมติว่าคุณมีความคิดที่ยอดเยี่ยมสำหรับผลิตภัณฑ์ใหม่ (เช่น Twitter, Facebook หรือ Instagram ถัดไป เพราะเราไม่สามารถมีสังคมมากเกินไปใช่ไหม) ในการเริ่มต้น คุณต้องการสร้างต้นแบบหรือ M inimum V iable P roduct (MVP) ของผลิตภัณฑ์นี้ เป้าหมายคือการสร้างแกนหลักของแอปให้เร็วที่สุด เพื่อให้คุณสามารถแสดงให้ผู้ใช้เห็นและรับข้อเสนอแนะและวิเคราะห์การใช้งาน โดยเน้นที่ความเร็วของการพัฒนาและการวนซ้ำอย่างรวดเร็วเป็นอย่างมาก
แต่ก่อนที่เราจะเริ่มสร้าง ผลิตภัณฑ์ที่น่าทึ่งของเราต้องการชื่อ เรียกมันว่า “Amazeballs” มันจะเป็น ตำนาน - รอก่อน - ดารี่ !
นี่คือภาพที่ฉันจินตนาการ:
แอพ Amazeballs ของเรา — แน่นอน — ทั้งหมดเกี่ยวกับการแบ่งปันเกร็ดเล็กเกร็ดน้อยเกี่ยวกับชีวิตส่วนตัวของคุณกับเพื่อน ๆ ในสิ่งที่เรียกว่า Balls ที่ด้านบนสุดคือแบบฟอร์มการโพสต์บอล ด้านล่างคือบอลของเพื่อนของคุณ
เมื่อสร้าง MVP คุณจะต้องมีเครื่องมือที่ช่วยให้คุณนำฟีเจอร์หลักไปใช้ได้อย่างรวดเร็ว เช่นเดียวกับความยืดหยุ่นในการเพิ่มและเปลี่ยนแปลงฟีเจอร์ในภายหลังอย่างรวดเร็ว ตัวเลือกของฉันอยู่ที่ Vue.js เนื่องจากเป็นเฟรมเวิร์กการแสดงผล Javascript ซึ่งสนับสนุนโดยชุด Firebase (โดย Google) และฐานข้อมูลแบบเรียลไทม์ใหม่ที่เรียกว่า Firestore
สามารถเข้าถึง Firestore ได้โดยตรงโดยใช้วิธี HTTP ปกติ ซึ่งทำให้เป็นโซลูชันแบ็กเอนด์-as-a-service เต็มรูปแบบ ซึ่งคุณไม่จำเป็นต้องจัดการเซิร์ฟเวอร์ใดๆ ของคุณเอง แต่ยังคงจัดเก็บข้อมูลออนไลน์
ฟังดูทรงพลังและน่าหวาดหวั่น แต่ไม่ต้องเหนื่อย ฉันจะแนะนำคุณตลอดขั้นตอนการสร้างและโฮสต์เว็บแอปใหม่นี้ สังเกตว่าแถบเลื่อนมีขนาดใหญ่เพียงใดในหน้านี้ มีขั้นตอนไม่มากนัก นอกจากนี้ หากคุณต้องการทราบว่าจะวางข้อมูลโค้ดแต่ละส่วนไว้ที่ใดในที่เก็บโค้ด คุณสามารถดู Amazeballs เวอร์ชันที่รันอย่างสมบูรณ์บน github ได้
เริ่มกันเลย
เรากำลังเริ่มต้นด้วย Vue.js เหมาะอย่างยิ่งสำหรับผู้เริ่มต้นใช้งาน Javascript เมื่อคุณเริ่มใช้งาน HTML และค่อยๆ เพิ่มตรรกะลงไป แต่อย่าประมาท มันบรรจุคุณสมบัติที่ทรงพลังมากมาย การรวมกันนี้ทำให้เป็นตัวเลือกแรกของฉันสำหรับเฟรมเวิร์กส่วนหน้า
Vue.js มีอินเตอร์เฟสบรรทัดคำสั่ง (CLI) สำหรับโครงการนั่งร้าน เราจะใช้สิ่งนั้นเพื่อตั้งค่ากระดูกเปล่าอย่างรวดเร็ว ขั้นแรก ติดตั้ง CLI จากนั้นใช้เพื่อสร้างโครงการใหม่โดยใช้เทมเพลต "webpack-simple"
npm install -g vue-cli vue init webpack-simple amazeballs
หากคุณทำตามขั้นตอนบนหน้าจอ ( npm install
และ npm run dev
) เบราว์เซอร์จะเปิดขึ้นพร้อมโลโก้ Vue.js ขนาดใหญ่
ยินดีด้วย! นั่นเป็นเรื่องง่าย
ต่อไป เราต้องสร้างโปรเจ็กต์ Firebase ตรงไปที่ https://console.firebase.google.com/ และสร้างโครงการ โปรเจ็กต์เริ่มต้นในแผน Spark ฟรี ซึ่งให้ฐานข้อมูลที่จำกัดแก่คุณ (ข้อมูล 1 GB, อ่าน 50,000 ครั้งต่อวัน) และโฮสติ้ง 1 GB เท่านี้ก็เพียงพอแล้วสำหรับ MVP ของเรา และสามารถอัพเกรดได้อย่างง่ายดายเมื่อแอปได้รับความสนใจ
คลิกที่ 'เพิ่ม Firebase ลงในเว็บแอปของคุณ' เพื่อแสดงการกำหนดค่าที่คุณต้องการ เราจะใช้การกำหนดค่านี้ในแอปพลิเคชันของเรา แต่ในลักษณะ Vue.js ที่ดีโดยใช้สถานะที่ใช้ร่วมกัน
ก่อน npm install firebase
จากนั้นสร้างไฟล์ชื่อ src/store.js นี่คือจุดที่เราจะใส่สถานะที่ใช้ร่วมกันเพื่อให้แต่ละองค์ประกอบ Vue.js สามารถเข้าถึงได้โดยอิสระจากโครงสร้างองค์ประกอบ ด้านล่างเป็นเนื้อหาของไฟล์ ขณะนี้รัฐมีตัวยึดตำแหน่งบางส่วนเท่านั้น
import Vue from 'vue'; import firebase from 'firebase/app'; import 'firebase/firestore'; // Initialize Firebase, copy this from the cloud console // Or use mine :) var config = { apiKey: "AIzaSyDlRxHKYbuCOW25uCEN2mnAAgnholag8tU", authDomain: "amazeballs-by-q42.firebaseapp.com", databaseURL: "https://amazeballs-by-q42.firebaseio.com", projectId: "amazeballs-by-q42", storageBucket: "amazeballs-by-q42.appspot.com", messagingSenderId: "972553621573" }; firebase.initializeApp(config); // The shared state object that any vue component can get access to. // Has some placeholders that we'll use further on! export const store = { ballsInFeed: null, currentUser: null, writeBall: (message) => console.log(message) };
ตอนนี้เราจะเพิ่มส่วน Firebase โค้ดชิ้นเดียวเพื่อรับข้อมูลจาก Firestore:
// a reference to the Balls collection const ballsCollection = firebase.firestore() .collection('balls'); // onSnapshot is executed every time the data // in the underlying firestore collection changes // It will get passed an array of references to // the documents that match your query ballsCollection .onSnapshot((ballsRef) => { const balls = []; ballsRef.forEach((doc) => { const ball = doc.data(); ball.id = doc.id; balls.push(ball); }); store.ballsInFeed = balls; });
จากนั้นแทนที่ฟังก์ชัน writeBall
ด้วยฟังก์ชันที่ดำเนินการเขียนจริง:
writeBall: (message) => ballsCollection.add({ createdOn: new Date(), author: store.currentUser, message })
สังเกตว่าทั้งสองแยกจากกันได้อย่างไร เมื่อคุณแทรกลงในคอลเลกชัน onSnapshot
จะถูกทริกเกอร์เนื่องจากคุณได้แทรกรายการ ทำให้การจัดการของรัฐง่ายขึ้นมาก
ตอนนี้คุณมีอ็อบเจ็กต์สถานะที่ใช้ร่วมกันซึ่งคอมโพเนนต์ Vue.js ใด ๆ สามารถเข้าถึงได้ง่าย มาใช้ให้เกิดประโยชน์กันเถอะ
โพสต์เรื่อง!
ก่อนอื่น มาดูกันว่าใครคือผู้ใช้ปัจจุบัน
Firebase มี API การตรวจสอบสิทธิ์ที่ช่วยคุณในการทำความรู้จักกับผู้ใช้ของคุณ เปิดใช้งานสิ่งที่เหมาะสมบน Firebase Console ใน Authentication → Sign In Method ในตอนนี้ ฉันจะใช้การเข้าสู่ระบบของ Google — ด้วยปุ่มที่ไม่ธรรมดา
Firebase ไม่ได้ให้ความช่วยเหลือด้านอินเทอร์เฟซใดๆ แก่คุณ ดังนั้น คุณจะต้องสร้างปุ่ม "เข้าสู่ระบบด้วย Google/Facebook/Twitter" ของคุณเอง และ/หรือช่องป้อนชื่อผู้ใช้/รหัสผ่าน องค์ประกอบการเข้าสู่ระบบของคุณอาจมีลักษณะดังนี้:
<template> <div> <button @click.prevent="signInWithGoogle">Log in with Google</button> </div> </template> <script> import firebase from 'firebase/app'; import 'firebase/auth'; export default { methods: { signInWithGoogle() { var provider = new firebase.auth.GoogleAuthProvider(); firebase.auth().signInWithPopup(provider); } } } </script>
ตอนนี้มีปริศนาการเข้าสู่ระบบอีกชิ้นหนึ่ง และนั่นคือการรับตัวแปร currentUser
ในร้านค้า เพิ่มบรรทัดเหล่านี้ใน store.js ของคุณ:
// When a user logs in or out, save that in the store firebase.auth().onAuthStateChanged((user) => { store.currentUser = user; });
เนื่องจากสามบรรทัดนี้ ทุกครั้งที่ผู้ใช้ที่เข้าสู่ระบบในปัจจุบันเปลี่ยนแปลง (เข้าสู่ระบบหรือออกจากระบบ) store.currentUser
ก็จะเปลี่ยนไปเช่นกัน มาโพสต์บอลกัน!
แบบฟอร์มอินพุตเป็นส่วนประกอบ Vue.js แยกต่างหากที่เชื่อมต่อกับฟังก์ชัน writeBall
ในร้านค้าของเรา ดังนี้:
<template> <form @submit.prevent="formPost"> <textarea v-model="message" /> <input type="submit" value="DUNK!" /> </form> </template> <script> import { store } from './store'; export default { data() { return { message: null, }; }, methods: { formPost() { store.writeBall(this.message); } }, } </script>
สุดยอด! ตอนนี้ผู้คนสามารถเข้าสู่ระบบและเริ่มโพสต์บอลได้ แต่เดี๋ยวก่อน เราขาดการอนุญาต เราต้องการให้คุณโพสต์ Balls ได้ด้วยตัวเองเท่านั้น และนั่นคือที่มาของ กฎ Firestore ซึ่งประกอบขึ้นจากโค้ด Javascript-ish ที่กำหนดสิทธิ์การเข้าถึงฐานข้อมูล คุณสามารถป้อนข้อมูลเหล่านี้ผ่านคอนโซล Firestore แต่คุณยังสามารถใช้ Firebase CLI เพื่อติดตั้งจากไฟล์บนดิสก์ได้ ติดตั้งและเรียกใช้ดังนี้:
npm install -g firebase-tools firebase login firebase init firestore
คุณจะได้รับไฟล์ชื่อ firestore.rules ซึ่งคุณสามารถเพิ่มการอนุญาตสำหรับแอปของคุณได้ เราต้องการให้ผู้ใช้ทุกคนสามารถใส่ลูกบอลของตัวเองได้ แต่ไม่สามารถแทรกหรือแก้ไขลูกบอลของคนอื่นได้ ตัวอย่างด้านล่างทำอย่างสวยงาม อนุญาตให้ทุกคนอ่านเอกสารทั้งหมดในฐานข้อมูล แต่คุณสามารถแทรกได้ก็ต่อเมื่อคุณลงชื่อเข้าใช้ และทรัพยากรที่แทรกมีฟิลด์ "ผู้เขียน" ที่เหมือนกับผู้ใช้ที่เข้าสู่ระบบอยู่ในปัจจุบัน
service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read: if true; allow create: if request.auth.uid != null && request.auth.uid == request.resource.data.author; } } }
ดูเหมือนโค้ดเพียงไม่กี่บรรทัด แต่มีประสิทธิภาพมากและสามารถซับซ้อนได้อย่างรวดเร็ว Firebase กำลังทำงานเกี่ยวกับเครื่องมือที่ดีขึ้นในส่วนนี้ แต่สำหรับตอนนี้ เป็นการลองผิดลองถูกจนกว่าจะได้ทำงานตามที่คุณต้องการ
หากคุณเรียกใช้ firebase deploy
กฎ Firestore จะถูกปรับใช้และรักษาความปลอดภัยข้อมูลการผลิตของคุณในไม่กี่วินาที
การเพิ่มลอจิกเซิร์ฟเวอร์
ในหน้าแรกของคุณ คุณต้องการดูไทม์ไลน์กับลูกบอลของเพื่อนๆ ขึ้นอยู่กับว่าคุณต้องการกำหนดว่าผู้ใช้เห็น Ball ใด การดำเนินการสืบค้นนี้โดยตรงบนฐานข้อมูลอาจเป็นปัญหาคอขวดของประสิทธิภาพ อีกทางเลือกหนึ่งคือการสร้าง Firebase Cloud Function ที่เปิดใช้งานในทุก Ball ที่โพสต์และผนวกเข้ากับผนังของเพื่อนของผู้เขียนทั้งหมด วิธีนี้จะเป็นแบบอะซิงโครนัส ไม่บล็อก และสอดคล้องกันในที่สุด หรืออีกนัยหนึ่ง มันจะไปถึงที่นั่น
เพื่อให้ตัวอย่างเรียบง่าย ฉันจะสาธิตการฟัง Balls ที่สร้างขึ้นและแก้ไขข้อความของพวกเขา ไม่ใช่เพราะสิ่งนี้มีประโยชน์อย่างยิ่ง แต่เพื่อแสดงให้คุณเห็นว่าการเรียกใช้ฟังก์ชันระบบคลาวด์เป็นเรื่องง่ายเพียงใด
const functions = require('firebase-functions'); exports.createBall = functions.firestore .document('balls/{ballId}') .onCreate(event => { var createdMessage = event.data.get('message'); return event.data.ref.set({ message: createdMessage + ', yo!' }, {merge: true}); });
โอ้ เดี๋ยวก่อน ฉันลืมบอกคุณว่าจะเขียนโค้ดนี้ที่ไหน
firebase init functions
สิ่งนี้จะสร้างไดเร็กทอรี functions ด้วย index.js นั่นคือไฟล์ที่คุณสามารถเขียน Cloud Functions ของคุณเอง หรือคัดลอกและวางของฉันหากคุณประทับใจกับมันมาก
Cloud Functions ช่วยให้คุณมีจุดที่ดีในการแยกส่วนต่างๆ ของแอปพลิเคชันออกและให้ส่วนต่างๆ สื่อสารแบบอะซิงโครนัส หรือในรูปแบบการวาดภาพสถาปัตยกรรม:
ขั้นตอนสุดท้าย: การปรับใช้
Firebase มีตัวเลือกการโฮสต์สำหรับสิ่งนี้ และคุณสามารถใช้ผ่าน Firebase CLI
firebase init hosting
เลือก dist
เป็นไดเรกทอรีสาธารณะ แล้วเลือก 'ใช่' เพื่อเขียน URL ใหม่ทั้งหมดเป็น index.html
ตัวเลือกสุดท้ายนี้ช่วยให้คุณใช้ vue-router เพื่อจัดการ URL ที่สวยงามภายในแอปของคุณได้
ตอนนี้มีอุปสรรคเล็กน้อย: โฟลเดอร์ dist
ไม่มีไฟล์ index.html
ที่ชี้ไปยังบิลด์ที่ถูกต้องของโค้ดของคุณ ในการแก้ไขปัญหานี้ ให้เพิ่มสคริปต์ npm ใน package.json
ของคุณ:
{ "scripts": { "deploy": "npm run build && mkdir dist/dist && mv dist/*.* dist/dist/ && cp index.html dist/ && firebase deploy" } }
ตอนนี้เพียงแค่เรียกใช้ npm deploy
และ Firebase CLI จะแสดง URL ของรหัสโฮสต์ของคุณ!
เมื่อใดควรใช้สถาปัตยกรรมนี้
การตั้งค่านี้เหมาะสำหรับ MVP เมื่อทำเช่นนี้เป็นครั้งที่สาม คุณจะมีเว็บแอปที่ใช้งานได้ภายในไม่กี่นาที ซึ่งได้รับการสนับสนุนจากฐานข้อมูลที่ปรับขนาดได้ซึ่งโฮสต์ไว้ฟรี คุณสามารถเริ่มสร้างคุณลักษณะได้ทันที
นอกจากนี้ยังมีพื้นที่มากมายให้เติบโต หาก Cloud Functions มีประสิทธิภาพไม่เพียงพอ คุณสามารถถอยกลับไปใช้ API แบบเดิมที่ทำงานบน Docker ใน Google Cloud ได้ นอกจากนี้ คุณสามารถอัพเกรดสถาปัตยกรรม Vue.js ของคุณด้วย vue-router
และ vuex
และใช้พลังของ webpack ที่รวมอยู่ในเทมเพลต vue-cli
ไม่ใช่รุ้งและยูนิคอร์นทั้งหมด ข้อแม้ที่ฉาวโฉ่ที่สุดคือลูกค้าของคุณกำลังพูดคุยกับฐานข้อมูลของคุณทันที ไม่มีเลเยอร์มิดเดิลแวร์ที่คุณสามารถใช้แปลงข้อมูลดิบให้อยู่ในรูปแบบที่ง่ายกว่าสำหรับลูกค้า ดังนั้น คุณต้องเก็บไว้ในวิธีที่เป็นมิตรกับลูกค้า เมื่อใดก็ตามที่ลูกค้าร้องขอการเปลี่ยนแปลง คุณจะพบว่าการเรียกใช้การย้ายข้อมูลบน Firebase ทำได้ค่อนข้างยาก สำหรับสิ่งนั้น คุณจะต้องเขียนไคลเอนต์ Firestore แบบกำหนดเองที่อ่านทุกระเบียน แปลง และเขียนกลับ
ใช้เวลาในการตัดสินใจเกี่ยวกับโมเดลข้อมูลของคุณ หากคุณต้องการเปลี่ยนโมเดลข้อมูลในภายหลัง การย้ายข้อมูลเป็นทางเลือกเดียวของคุณ
“
ตัวอย่างโครงการที่ใช้เครื่องมือเหล่านี้มีอะไรบ้าง ในบรรดาชื่อใหญ่ๆ ที่ใช้ Vue.js ได้แก่ Laravel, GitLab และ (สำหรับชาวดัตช์) nu.nl Firestore ยังอยู่ในช่วงเบต้า จึงมีผู้ใช้งานไม่มากนัก แต่ชุด Firebase ถูกใช้งานโดย National Public Radio , Shazam และอื่นๆ ฉันเคยเห็นเพื่อนร่วมงานใช้ Firebase สำหรับเกม Road Warriors ที่ใช้ Unity ซึ่งดาวน์โหลดมากกว่าล้านครั้งในห้าวันแรก มันสามารถโหลดได้ค่อนข้างมาก และมันใช้งานได้หลากหลายมากกับไคลเอนต์สำหรับเว็บ เนทีฟ โมบายล์ Unity และอื่นๆ
สมัครได้ที่ไหน!
หากคุณต้องการเรียนรู้เพิ่มเติม ให้พิจารณาแหล่งข้อมูลต่อไปนี้:
- ตัวอย่างการทำงานที่มีโค้ดด้านบนทั้งหมด
- เอกสารเกี่ยวกับ Vue.js, vue-router, vue-cli
- เอกสารเกี่ยวกับ Firebase
- วิธีที่สนุกสนานในการทำความรู้จัก Firebase ให้ดีขึ้น — YouTube Blog
มีความสุขในการเข้ารหัส!