ลงสนามด้วย Vue.js และ Firestore

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ การสร้าง MVP นั้นเกี่ยวกับการสร้างฟังก์ชันการทำงานจำนวนมากในระยะเวลาอันสั้น Vue.js เป็นตัวเลือกที่ดี ด้วยสถาปัตยกรรมสำเร็จรูปขั้นต่ำและพลังงานดิบจำนวนมาก สิ่งที่ต้องการคือที่เก็บข้อมูล

Google Firebase มีความเป็นไปได้ในการจัดเก็บข้อมูลแบบใหม่ที่เรียกว่า 'Firestore' (ปัจจุบันอยู่ในช่วงเบต้า) ซึ่งต่อยอดจากความสำเร็จของ Firebase Realtime Database แต่ได้เพิ่มคุณลักษณะที่ดีบางอย่างเข้าไป ในบทความนี้ เราจะตั้งค่าพื้นฐานของเว็บแอปโดยใช้ Vue.js และ Firestore

สมมติว่าคุณมีความคิดที่ยอดเยี่ยมสำหรับผลิตภัณฑ์ใหม่ (เช่น Twitter, Facebook หรือ Instagram ถัดไป เพราะเราไม่สามารถมีสังคมมากเกินไปใช่ไหม) ในการเริ่มต้น คุณต้องการสร้างต้นแบบหรือ M inimum V iable P roduct (MVP) ของผลิตภัณฑ์นี้ เป้าหมายคือการสร้างแกนหลักของแอปให้เร็วที่สุด เพื่อให้คุณสามารถแสดงให้ผู้ใช้เห็นและรับข้อเสนอแนะและวิเคราะห์การใช้งาน โดยเน้นที่ความเร็วของการพัฒนาและการวนซ้ำอย่างรวดเร็วเป็นอย่างมาก

แต่ก่อนที่เราจะเริ่มสร้าง ผลิตภัณฑ์ที่น่าทึ่งของเราต้องการชื่อ เรียกมันว่า “Amazeballs” มันจะเป็น ตำนาน - รอก่อน - ดารี่ !

นี่คือภาพที่ฉันจินตนาการ:

สกรีนช็อตของแอพ Amazeballs
แอพ 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 ใน AuthenticationSign In Method ในตอนนี้ ฉันจะใช้การเข้าสู่ระบบของ Google — ด้วยปุ่มที่ไม่ธรรมดา

สกรีนช็อตของหน้าเข้าสู่ระบบด้วยการตรวจสอบสิทธิ์ของ Google
การตรวจสอบสิทธิ์ด้วย Google Login

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 ก็จะเปลี่ยนไปเช่นกัน มาโพสต์บอลกัน!

ภาพหน้าจอของตัวเลือกออกจากระบบ
สถานะการเข้าสู่ระบบถูกเก็บไว้ในไฟล์ store.js

แบบฟอร์มอินพุตเป็นส่วนประกอบ 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 ช่วยให้คุณมีจุดที่ดีในการแยกส่วนต่างๆ ของแอปพลิเคชันออกและให้ส่วนต่างๆ สื่อสารแบบอะซิงโครนัส หรือในรูปแบบการวาดภาพสถาปัตยกรรม:

ไดอะแกรมสถาปัตยกรรมลอจิกเซิร์ฟเวอร์ของ 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

มีความสุขในการเข้ารหัส!