Начните работать с Vue.js и Firestore
Опубликовано: 2022-03-10В Google Firebase есть новая возможность хранения данных под названием «Firestore» (в настоящее время находится на стадии бета-тестирования), которая основана на успехе базы данных Firebase Realtime , но добавляет несколько отличных функций. В этой статье мы настроим основы веб-приложения, используя Vue.js и Firestore.
Допустим, у вас есть отличная идея для нового продукта (например, следующий Twitter, Facebook или Instagram, потому что социальных сетей никогда не бывает слишком много, верно?). Для начала вы хотите создать прототип или минимально жизнеспособный продукт (MVP) этого продукта. Цель состоит в том, чтобы как можно быстрее создать ядро приложения, чтобы вы могли показывать его пользователям, получать отзывы и анализировать использование. Особое внимание уделяется скорости разработки и быстрой итерации.
Но прежде чем мы начнем строить, нашему удивительному продукту нужно дать имя. Назовем это «Amazeballs». Это будет легенда — подождите — черт возьми !
Вот снимок того, как я это себе представляю:
Наше приложение Amazeballs, конечно же, предназначено для того, чтобы делиться пикантными подробностями своей личной жизни с друзьями в так называемых Balls. Вверху находится форма для публикации Балов, ниже - Балы ваших друзей.
При создании MVP вам потребуются инструменты, которые дадут вам возможность быстро реализовать ключевые функции, а также гибкость для быстрого добавления и изменения функций позже. Мой выбор падает на Vue.js, так как это среда рендеринга Javascript, поддерживаемая набором Firebase (от Google) и его новой базой данных в реальном времени под названием Firestore.
Доступ к Firestore возможен напрямую с использованием обычных HTTP-методов, что делает его полным бэкэнд-решением как услугой, в котором вам не нужно управлять какими-либо собственными серверами, но при этом хранить данные в Интернете.
Звучит мощно и устрашающе, но не беспокойтесь, я проведу вас через этапы создания и размещения этого нового веб-приложения. Обратите внимание, насколько велика полоса прокрутки на этой странице; там не так много шагов. Кроме того, если вы хотите знать, куда поместить каждый из фрагментов кода в хранилище кода, вы можете увидеть полностью работающую версию 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 ГБ данных, 50 000 операций чтения в день) и 1 ГБ хостинга. Этого более чем достаточно для нашего 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 в Authentication → Sign In Method . Сейчас я собираюсь использовать 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
также изменяется. Давайте разместим несколько шаров!
Форма ввода — это отдельный компонент 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>
Потрясающий! Теперь люди могут войти в систему и начать публиковать шары. Но подождите, нам не хватает авторизации. Мы хотим, чтобы вы могли публиковать шары только самостоятельно, и именно здесь вступают в действие правила Firestore . Они состоят из кода, похожего на Javascript, который определяет права доступа к базе данных. Вы можете ввести их через консоль Firestore, но вы также можете использовать интерфейс командной строки Firebase для их установки из файла на диске. Установите и запустите его следующим образом:
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 будут развернуты и защитят ваши производственные данные за считанные секунды.
Добавление логики сервера
На своей домашней странице вы хотите видеть временную шкалу с мячами ваших друзей. В зависимости от того, как вы хотите определить, какие мячи видит пользователь, выполнение этого запроса непосредственно в базе данных может стать узким местом в производительности. Альтернативой является создание облачной функции Firebase , которая активируется на каждом размещенном шаре и добавляет ее на стены всех друзей автора. Таким образом, он асинхронный, неблокирующий и в конечном итоге согласованный. Или, другими словами, он попадет туда.
Чтобы не усложнять примеры, я сделаю небольшую демонстрацию прослушивания созданных шаров и изменения их сообщений. Не потому, что это особенно полезно, а для того, чтобы показать вам, как легко запустить облачные функции.
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 . Это файл, в который вы можете записать свои собственные облачные функции . Или скопировать и вставить мой, если он вас очень впечатлил.
Облачные функции дают вам удобное место для разделения различных частей вашего приложения и их асинхронного взаимодействия. Или, в стиле архитектурного рисунка:
Последний шаг: развертывание
Для этого в Firebase есть опция хостинга, и вы можете использовать ее через интерфейс командной строки Firebase.
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 покажет вам URL вашего размещенного кода!
Когда использовать эту архитектуру
Эта установка идеально подходит для MVP. К третьему разу, когда вы сделаете это, у вас будет работающее веб-приложение за считанные минуты, поддерживаемое масштабируемой базой данных, которая размещается бесплатно. Вы можете сразу приступить к созданию функций.
Кроме того, есть много места для роста. Если облачные функции недостаточно эффективны, вы можете вернуться к традиционному API, работающему, например, в докере в Google Cloud. Кроме того, вы можете обновить архитектуру Vue.js с помощью vue-router
и vuex
и использовать возможности веб-пакета, включенного в шаблон 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
Удачного кодирования!