Создание сайтов в Дебальцево, ДНР. Как создать MVP с помощью React и Firebase

 
 

При прототипировании идеи рекомендуется упрощать и создавать только минимальные основные функции, необходимые для запуска продукта на рынке. Это поможет вам определить, соответствует ли ваше приложение требованиям рынка, прежде чем тратить время и деньги на продукт, который никому не интересен. Это называется «минимально жизнеспособным продуктом» (MVP). В этом руководстве вы узнаете, как создать MVP с помощью React и Firebase, платформы «бэкенд как услуга».

Чтобы обеспечить наибольшую ценность, мы не будем разрабатывать приложение React + Firebase шаг за шагом. Вместо этого я разберу рабочий прототип и объясню ключевые концепции, используя псевдоподобный язык программирования. Фактический код довольно многословен, так как это в основном интерфейсная логика, предназначенная для работы со многими аспектами, такими как управление состоянием, адаптивный дизайн пользовательского интерфейса и доступность.

Моя цель — показать вам архитектурный дизайн создания веб-интерфейсов, связанных с бессерверной серверной частью. Полный проект Firebase, который мы будем использовать, находится в нашем репозитории GitHub. В конце этого руководства вы сможете применять эти концепции в своих собственных веб-проектах MVP.

Почему Firebase?

Если вы хотите создать веб-приложение на бессерверной платформе, вы столкнетесь с множеством поставщиков, которые предлагают все основные услуги, необходимые для создания вашего продукта. Эти услуги включают аутентификацию, базу данных, облачные функции, хранилище, аналитику и многое другое.

Если бы вы выбрали лучшее в своем классе для каждой службы, у вас была бы довольно высокая кривая обучения, чтобы выяснить, как заставить все эти службы работать вместе в вашем приложении. Вы также подвергаете свой продукт ряду угроз безопасности, поскольку существует несколько конечных точек, к которым подключается ваш продукт для работы. Существуют меры по защите вашего приложения, но большинство разработчиков не знают, какие проблемы безопасности необходимо устранить.

Firebase — это серверная платформа как услуга, которая удобно предоставляет ряд основных услуг под одной крышей. Это сокращает кривую обучения, а также упрощает создание безопасных веб-приложений и мобильных приложений.

Эти службы Firebase включают в себя:

аутентификация

база данных

место хранения

облачные функции

аналитика

хостинг

Предпосылки

Обратите внимание, что это руководство написано для разработчиков React среднего и продвинутого уровня, которые хотят быстро научиться использовать Firebase для своих проектов. Я предоставил несколько дополнительных тем, с которыми вам необходимо ознакомиться, прежде чем продолжить:

Реагировать и TailwindCSS

Реагировать на запрос

Vite — лучшая альтернативаcreate-react-app

План проекта Firebase

Проект, который мы рассмотрим, представляет собой простую онлайн-библиотеку, в которой данные организованы по книгам, авторам и категориям. Ниже приведена диаграмма отношений сущностей.

диаграмма отношений сущностей

Логика приложения была организована в:

экранные контейнеры (страницы или представления)

презентационные компоненты (формы, таблицы)

компоненты макета (нижний колонтитул, панель навигации)

общие компоненты пользовательского интерфейса (оповещения, модальные окна, заголовки страниц)

Сервисы Firebase (база данных, хранилище)

Сценарии конфигурации Firebase (внутренние соединители)

Ниже приведена иллюстрация основной архитектуры проекта:

схема архитектуры приложения

Мы будем использовать следующую структуру папок для организации нашего кода:

├── components

│ ├── entity (e.g. book)

│ │ ├── Card.jsx (→ BookCard)

│ │ ├── Detail.jsx (→ BookDetail)

│ │ ├── Form.jsx

│ │ └── List.jsx

│ └── ui

│ └── Component.jsx (e.g. PageHeader, Alert)

├── layout

│ ├── Footer.jsx

│ └── Navbar.jsx

├── screens

│ ├── entity

│ │ ├── Detail.jsx (→ ScreenBookDetail)

│ │ ├── Form.jsx (→ ScreenBookForm)

│ │ └── List.jsx

│ ├── category

│ │ ├── Form.jsx

│ │ └── List.jsx

│ ├── Home.jsx

│ └── NotFound.jsx

└── services

└── Service.js (e.g. Database, Storage)

Символ →обозначает пример того, как называется функциональный компонент. Ознакомьтесь с этим руководством для получения дополнительной информации о соглашениях об именах для интерфейсных приложений.

Настройка проекта Firebase

Проект, который мы будем использовать, был создан с использованием шаблона Vite + React. Чтобы настроить проект в рабочей области, просто откройте терминал и выполните следующее:

# Clone project

git clone git@github.com:sitepoint-editors/sitepoint-books-firebase.git

author_id (ссылка) /авторы/{идентификатор места} /авторы/{идентификатор места}

category_id (ссылка) /categories/{идентификатор места} /categories/{идентификатор места}

Описание Это простое и увлекательное руководство — идеальное место для начала вашего пути к программированию. Вы будете учиться программировать на JavaScript — самом популярном языке программирования на Земле, — но методы, которые вы освоите, дадут вам основу для дальнейшего использования и на других языках. Эта книга представляет собой сборник подробных руководств по некоторым инструментам, наиболее часто используемым в науке о данных, таким как Pandas и PySpark, а также обзор некоторых навыков, которые вам понадобятся как специалисту по данным.

URL-адрес https://www.sitepoint.com/premium/books/learn-to-code-with-javascript/ https://www.sitepoint.com/premium/books/data-science-tools-skills/

См. скриншот ниже в качестве примера того, как настроить структуру базы данных.

облачная база данных firestore

Запуск сервера разработки

Теперь, когда база данных заполнена, мы можем выполнить npm run devи перейти localhost:3000к взаимодействию с проектом. Обратите внимание, что это прототип приложения, созданный для обучения, и не все функции реализованы полностью.

подробное описание книги приложений

Логика проекта Firebase

Давайте теперь начнем разбирать проект, чтобы вы могли узнать, как внешние интерфейсы построены для подключения и взаимодействия с серверной частью Firebase. Основное внимание в этом руководстве будет уделено логике управления состоянием. Если вы не знакомы с кодом пользовательского интерфейса, используемым в этом проекте Firebase, обратитесь к следующей документации по библиотекам пользовательского интерфейса, используемым в проекте:

TailwindCSS и плагины: основной CSS-фреймворк

HeadlessUI: небольшая коллекция нестилизованных компонентов пользовательского интерфейса.

HeroIcons: коллекция SVG-иконок, созданных вручную командой Tailwind CSS.

DaisyUI: библиотека компонентов TailwindCSS

React Hook Form: формировать государственную библиотеку

Ага: библиотека проверки формы

Маршрутизация

Создание интерфейса CRUD для проекта, в котором задействовано более двух объектов, может быстро усложниться. Для маршрутизации я использовал React Router и реализовал структуру маршрутизации, используя стандартизированный синтаксис. То есть:

список маршрутов: /{entity}

создать маршрут: /{entity}/create

изменить маршрут: /{entity}/edit/: id

подробный маршрут: /{entity}/: id

Вот упрощенное представление о том, как маршрутизация была реализована в App.jsx:

import React from «react»;

import { Route, Switch } from «react-router-dom»;

// Layout components

import Footer from «@/layout/Footer»;

import Navbar from «@/layout/Navbar»;

// Screen (pages or views) containers

import Home from «@/screens/Home»;

import NotFound from «@/screens/NotFound»;

import ScreenBookList from «@/screens/book/List»;

import ScreenBookForm from «@/screens/book/Form»;

import ScreenBookDetail from «@/screens/book/Detail»;

function App () {

return (

</>

) ;

}

Обратите внимание, что ScreenBookFormон был повторно использован как для создания, так и для редактирования маршрутов. Позже вы увидите, как можно использовать один контейнер формы для обработки обоих вариантов использования. Далее мы рассмотрим, как приложение React подключается к серверной части Firebase.

Служба базы данных

Для веб-приложений, мобильных приложений и приложений Node.js в вашем проекте должен быть установлен официальный пакет Firebase. Этот пакет содержит все инструменты, необходимые для подключения к различным внутренним службам Firebase:

npm install firebase

Чтобы подключиться к вашей базе данных Cloud Firestore, вам необходимо определить следующее в firebase.js:

import firebase from «firebase/app»; // include the Firebase module

import «firebase/firestore»; // access firestore database service

const firebaseConfig = {

apiKey: import.meta.env.VITE_API_FIREBASE_API_KEY,

authDomain: import.meta.env.VITE_API_FIREBASE_AUTH_DOMAIN,

projectId: import.meta.env.VITE_API_FIREBASE_PROJECT_ID,

storageBucket: import.meta.env.VITE_API_FIREBASE_STORAGE_BUCKET,

messagingSenderId: import.meta.env.VITE_API_FIREBASE_MESSAGING_SENDER_ID,

appId: import.meta.env.VITE_API_FIREBASE_APP_ID,

};

// Initialize Firebase

const app = firebase.initializeApp (firebaseConfig) ;

export const db = app.firestore () ;

export default app;

Затем вы можете импортировать dbобъект в любой контейнер React и начать напрямую запрашивать базу данных. Я предпочитаю сначала создать, services/DatabaseService.jsкоторый включает всю необходимую логику CRUD:

import { db } from «@/firebase»;

class DatabaseService {

collection;

// Specify 'authors’, 'categories’, or 'books’ as collection name

constructor (collectionName) {

this.collection = db.collection (collectionName) ;

}

// returns list of records as an array of javascript objects

getAll = async () => {

const snapshot = await this.collection.get () ;

return snapshot.docs.map ((doc) => {

return {

id: doc.id, // append document id to each document

...doc.data (),

};

}) ;

};

// returns a single document in object format

getOne = async ({ queryKey }) => {

const { id } = queryKey[1];

if (! id) return; // entity form is in create mode

const snapshot = await this.collection.doc (id).get () ;

return snapshot.data () ;

};

// resolve a relation, returns the referenced document

getReference = async (documentReference) => {

const res = await documentReference.get () ;

const data = res.data () ;

if (data && documentReference.id) {

data.uid = documentReference.id;

}

return data;

};

// save a new document in the database

create = async (data) => {

return await this.collection.add (data) ;

};

// update an existing document with new data

update = async (id, values) => {

return await this.collection.doc (id).update (values) ;

};

// delete an existing document from the collection

remove = async (id) => {

return await this.collection.doc (id).delete () ;

};

}

// Create services for each entity type

export const AuthorService = new DatabaseService («authors») ;

export const CategoryService = new DatabaseService («categories») ;

export const BookService = new DatabaseService («books») ;

В приведенном выше коде есть два основных компонента:

Класс DatabaseService, который содержит логику CRUD — то есть чтение (getAll, getOne), создание, обновление и удаление.

Экземпляры службы базы данных для каждого из типов коллекций, с которыми мы работаем, то есть books, categoriesи authors. Мы будем использовать это в компонентах контейнера (экрана) для взаимодействия с нашей серверной частью Firebase.

Некоторые дополнительные примечания для DatabaseServiceкласса:

Для getAllметода, когда вы вызываете data.doc () метод, вы получаете только значения данных без идентификатора объекта. Чтобы исправить это, нам нужно вызвать doc.idи объединить его с остальными значениями. Это необходимо для того, чтобы операции обновления и удаления работали.

Я объясню эту getReferenceфункцию позже в разделе «Разрешение отношений документов».

Для получения дополнительной информации об остальных функциях обратитесь к встроенным комментариям и документации Firestore.

Имея службу базы данных, давайте посмотрим, как данные извлекаются и используются для заполнения внешнего интерфейса.

Список документов

Теперь, когда мы настроили нашу службу базы данных, нам нужно вызвать ее из контейнера, например ScreenAuthorList. Как только данные будут получены, они будут переданы через реквизиты компоненту презентации, то есть AuthorList.

список авторов

Для управления данными сервера в нашем интерфейсном приложении мы будем использовать React Query. Использование этого пакета намного проще, чем настройка Redux или любого другого внешнего решения для управления состоянием. Вот упрощенная версия ScreenAuthorList.jsx, демонстрирующая эту концепцию в действии:

import React from «react»;

import { useQuery } from «react-query»;

import { AuthorService } from «@/services/DatabaseService»;

import PageHeading from «@/components/ui/PageHeading»;

import AuthorList from «@/components/author/List»;

function ScreenAuthorList () {

const { data, status } = useQuery («authors», AuthorService.getAll) ;

return (

<>

 

{status === «success» && }

 

</>

) ;

}

export default ScreenAuthorList;

А вот упрощенная версия AuthorList.jsx, которая просто принимает данные и отображает их в виде таблицы:

import React from «react»;

import { Link } from «react-router-dom»;

function AuthorList ({ data }) {

return (

 

{data.map ((author, index) => (

))}

Name
{author.name}

) ;

}

export default AuthorList;

Обратите внимание, что я исключил кнопки editи delete, которые мы рассмотрим далее.

Удаление документов с диалогом подтверждения

Кнопка Удалить в AuthorListкомпоненте определяется следующим образом:

...

...

 

<button

title={`Delete ${author.name}`}

onClick={ () => showDeleteModal (author.id) }

>

 

 

Давайте посмотрим, как showDeleteModal (id) функция определена в компоненте:

import React, { useState } from «react»;

function AuthorList ({ data, deleteAction }) {

const [selected, setSelected] = useState () ; // set author.id for deletion

const [openModal, setOpenModal] = useState (false) ; // show or hide DeleteModal

const showDeleteModal = (id) => {

setSelected (id) ;

setOpenModal (true) ;

};

const deleteModalAction = () => {

deleteAction (selected) ;

setOpenModal (false) ;

};

const cancelModalAction = () => {

setOpenModal (false) ;

};

return (

 

 

<DeleteModal

open={openModal}

deleteAction={deleteModalAction}

cancelAction={cancelModalAction}

/>

// delete button is here

 

 

) ;

}

По сути, при showDeleteModal (id) вызове функции происходит следующее:

состояние selectedустановлено на текущееauthor.id

диалоговое окно подтверждения настроено на видимость

Диалоговое окно подтверждения, также известное как DeleteModal.jsx, слишком многословно, чтобы отображать здесь полный код. Для простоты я использовал псевдоязык для определения его структуры, чтобы сделать его более читабельным:

function DeleteModal ({ isOpen, deleteAction, cancelAction }) {

return (

<modal-content>

{» «}

Are you sure you want to permanently remove this record forever? {» «}

modal-content>

<modal-footer>

modal-footer>

 

) ;

}

Функция cancelActionпросто скроет диалоговое окно подтверждения. Функция deleteActionвызовет обработчик базы данных, ответственный за фактическое удаление документа. Этот обработчик определяется на уровне контейнера ScreenAuthorList.jsx. Ниже приведен упрощенный вариант кода:

import { useMutation, useQueryClient } from «react-query»;

function ScreenAuthorList () {

const queryClient = useQueryClient () ;

const deleteMutation = useMutation ((id) => AuthorService.remove (id), {

onSuccess: () => {

queryClient.invalidateQueries («authors») ;

},

}) ;

const deleteAction = async (id) => {

deleteMutation.mutateAsync (id) ;

};

return (

<>

</>

) ;

}

После успешного удаления нам нужно вызвать queryClient.invalidateQueries (), чтобы убедиться, что изменение отражено во всех компонентах, кэширующих данные. Давайте теперь посмотрим, как документы создаются и обновляются через интерфейсный интерфейс.

Создание и обновление документов

Чтобы продемонстрировать, как создавать и обновлять документы, мы будем использовать AuthorForm.jsx, который проще всего объяснить.

форма автора приложения

Во-первых, нам нужно посмотреть на кнопки Createи Edit, которые направляют пользователей на ScreenAuthorFormстраницу. Это делается в AuthorList.jsxкомпоненте:

import { Link } from «react-router-dom»;

import { UserCircleIcon, PencilAltIcon } from «@heroicons/react/outline»;

function AuthorList () {

return (

 

 

 

 

 

New Author

 

 

 

 

 

...

 

 

...

 

 

<Link to={`/author/edit/${author.id}`} title={`Edit ${author.name}`}>

 

 

 

 

) ;

}

Контейнер ScreenAuthorFormпредназначен для обработки вариантов использования автора как создания, так и обновления. В случае обновления нам нужно получить idиз URL-адреса, а затем использовать его для получения документа для нашей базы данных Firebase. Для создания мы просто отобразим форму без передачи каких-либо значений:

import { useParams } from 'react-router-dom

function ScreenAuthorForm () {

const { id } = useParams () // retrieve id from url parameters

// fetch document

const { data, isLoading, error, status } = useQuery (

['author’, { id }],

AuthorService.getOne

)

// Render create form

if (! id) {

return (

<>

</>

)

}

// Render update form

return (

<>

<>

)

}

Мы не будем вдаваться в подробности того, как устроена форма, но я предоставлю вам упрощенную версию AuthorFormкомпонента:

import React, { useState, useEffect } from «react»;

import { useForm } from «react-hook-form»;

function AuthorForm ({ values, submit }) {

// initialize react-hook-form

const { register, reset, handleSubmit } = useForm () ;

// populate form fields

useEffect (() => {

reset (values) ;

}, [values]) ;

// call container submit handler to save new/updated values

const onSubmit = (submittedData) => {

submit (submittedData) ;

};

return (

 

 

 

 

 

 

 

 

 

Cancel

 

 

 

 

) ;

}

Встроенные комментарии должны объяснять основные разделы кода. Обратитесь к документации React Hook Form, чтобы узнать, как работает библиотека. Мы не смотрели на submitфункцию, поэтому давайте сделаем это сейчас в ScreenAuthorFormконтейнере:

import { useParams, Redirect } from 'react-router-dom

import { useQuery, useMutation, useQueryClient } from 'react-query

function ScreenAuthorForm () {

const { id } = useParams ()

const queryClient = useQueryClient ()

// call the database service to create or update document depending on presence of id

const saveData = (data) => {

if (id) {

return AuthorService.update (id, data)

} else {

AuthorService.create (data)

}

}

// create mutation

const mutation = useMutation ((data) => saveData (data), {

onSuccess: () => {

if (id) queryClient.invalidateQueries (['author’, { id }])

},

})

// track mutation status i.e. return true after successful mutation

const { isSuccess } = mutation

// define submit action handler to be passed down as prop to AuthorForm

const onSubmit = async (submittedData) => {

mutation.mutate (submittedData)

}

// if mutation is successful, redirect to ScreenAuthorList

if (isSuccess) {

return

}

// render create and update form

return (

...

...

)

...

}

Встроенные комментарии должны объяснять, что делает каждый блок кода. Обратитесь к документации по мутациям React Query, чтобы понять, как это работает. В следующем разделе мы рассмотрим, как мы можем отображать изображения, хранящиеся в службе облачного хранилища Firebase.

Отображение изображений

В этом разделе мы будем использовать CategoryCardдля демонстрации рендеринга изображений.

список категорий приложений

Напоминаем, вот пример данных категории:

{

«name»: «javascript»,

«cover»: «categories/javascript.png»

}

Если вы перейдете к одному из изображений, которые вы загрузили в облачное хранилище, вы увидите URL-ссылку в следующем формате:

gs: //.appspot.com//

Эта ссылка не может быть обработана браузером. Его необходимо преобразовать в ссылку для скачивания в формате HTTP. Для этого нам нужно импортировать пакет, который позволяет нашему приложению взаимодействовать со службой Firebase Storage. Это делается в firebase.js:

...

import 'firebase/storage’

...

export const storage = app.storage ()

Далее мы можем импортировать storageэкземпляр и определить функцию, которая будет выполнять это преобразование. Это было сделано в StorageService.js:

import { storage } from «.../firebase»;

const storageRef = storage.ref () ; // access the default bucket

// accepts file path in the format `folder/filename.ext`

const getImageURL = async (filePath) => {

const url = await storageRef.child (filePath).getDownloadURL () ;

return url;

};

const StorageService = {

getImageURL,

};

export default StorageService;

Теперь, когда мы настроили службу, которая будет обрабатывать для нас преобразование URL-адреса изображения, мы можем определить CategoryCardкомпонент следующим образом:

import React, { useEffect, useState } from «react»;

import { Link } from «react-router-dom»;

import StorageService from «.../... /services/StorageService»;

function CategoryCard ({ category }) {

const [imageLink, setImageLink] = useState () ;

// download the image link

useEffect (async () => {

const url = await StorageService.getImageURL (category.cover) ;

setImageLink (url) ;

}, [category]) ;

return (

 

 

<Link to={`/category/edit/${category.id}`}>

) ;

}

export default CategoryCard;

К сожалению, это совсем немного работы только для отображения изображения. Мы поговорим об этом позже в резюме. А пока давайте рассмотрим другую проблему, когда вам нужно разрешить пользователям выбирать из доступного списка файлов.

Список файлов

При работе с изображениями мы можем дать пользователям возможность загружать новые или выбирать из существующих. Обычно современные интерфейсы имеют браузеры активов, которые позволяют вам делать и то, и другое. Для простоты мы просто будем использовать базовый ввод для выбора из раскрывающегося списка.

Раскрывающееся меню категории приложений Firebase

Чтобы получить список файлов из облачного хранилища из определенной папки, нам нужна функция, которая может справиться с этой задачей в StorageService.js:

// input: folder name

// output: list of fileNames in array format

const listFiles = async (folder) => {

const listRef = storageRef.child (folder) ;

const res = await listRef.listAll () ;

const list = res.items.map ((itemRef) => itemRef. _delegate. _location.path_) ;

return list;

};

const StorageService = {

...listFiles,

};

Теперь, когда listFilesфункция определена, мы можем вызвать ее из CategoryForm компонента:

import React, { useState, useEffect } from «react»;

import StorageService from «.../... /services/StorageService»;

function CategoryForm ({ values, action }) {

const [coverOptions, setCoverOptions] = useState ([]) ;

// Get list of available images from cloud storage

useEffect (async () => {

const availableFiles = await StorageService.listFiles («categories») ;

setCoverOptions (availableFiles) ;

}, []) ;

return (

 

 

...

 

 

) ;

}

Используя асинхронную useEffectфункцию, мы можем получить имена файлов, а затем заполнить поле выбора через coverOptionsсостояние. В следующем разделе мы рассмотрим, как разрешать связи между документами.

Разрешение отношений документов

Если вспомнить bookструктуру сущности, она содержала ссылочные поля с именами author_idи category_id. Для большинства систем баз данных и библиотек ORM существует возможность заполнения ссылок значениями, так что для загрузки всех необходимых данных требуется только один запрос.

К сожалению, для базы данных Firestore вам необходимо выполнить дополнительные запросы для загрузки ссылочных документов. Нам нужно определить конкретную функцию для этого в DatabaseService.js:

class DatabaseService {

...

getReference = async (documentReference) => {

const res = await documentReference.get ()

const data = res.data ()

if (data && documentReference.id) {

data.uid = documentReference.id

}

return data

}

...

}

Теперь, когда функция определена, мы можем полностью загрузить документ со справочными полями. См. BookDetailкомпонент в качестве примера:

import { BookService } from «@/services/DatabaseService»;

function BookDetail ({ book }) {

const [author, setAuthor] = useState () ;

const [category, setCategory] = useState () ;

// Resolve book.author_id document reference

useEffect (async () => {

const authorRef = await BookService.getReference (book.author_id) ;

setAuthor (authorRef) ;

}, [book]) ;

// Resolve book.category_id document reference

useEffect (async () => {

const categoryRef = await BookService.getReference (book.category_id) ;

setCategory (categoryRef) ;

}, [book]) ;

return (

 

 

...

{category && {category.name}}

...

{author && By {author.name}}

...

 

 

) ;

}

В приведенном выше примере мы используем асинхронные useEffectперехватчики для выполнения дополнительных запросов. В следующем разделе мы начнем завершать статью.

Другие сервисы Firebase

К сожалению, существует множество сервисов Firebase, которые я не смогу описать в этой статье. Эти серверные службы очень важны для создания вашего приложения MVP Firebase. Итак, я сделаю краткий обзор некоторых из них:

Аутентификация. Этот сервис позволяет легко добавлять функции входа в ваше приложение Firebase. Он поддерживает электронную почту, учетные записи социальных сетей, GitHub и даже методы аутентификации по SMS. Аутентификация Firebase тесно интегрируется с другими сервисами Firebase и может быть легко интегрирована с вашим пользовательским сервером.

Облачные функции. Это сервис, который позволяет вам писать и выполнять внутренний код в ответ на события, вызванные функциями Firebase и HTTPS-запросами. Код написан на JavaScript/TypeScript и работает в управляемой среде Google Cloud.

Хостинг. Это сервис, предоставляющий хостинг веб-приложений, статического и динамического контента и микросервисов. Контент обслуживается через глобальную CDN (сеть доставки контента).

Аналитика. Вы можете использовать Google Analytics для сбора данных об использовании и поведении для вашего веб-приложения черезfirebase/analyticsпакет. Вы можете собирать и отслеживать события и пользовательские атрибуты (такие как язык, географический язык) вашей аудитории.

Как упоминалось ранее, настроенные нами правила безопасности разрешают общедоступный доступ для чтения и записи к нашему серверному интерфейсу. Чтобы узнать, как защитить свою учетную запись Firebase, я рекомендую ознакомиться с правилами безопасности. Обратите внимание, что вы также должны реализовать аутентификацию Firebase в своем приложении, чтобы разрешить безопасный доступ к данным.

Резюме

Подводя итог, вы научились:

структурировать и организовывать интерфейсный код

зарегистрировать приложение Firebase

заполнить базу данных и хранилище Firestore

получить как данные, так и файлы из серверной части Firebase

Связывание коллекций во внешнем пользовательском интерфейсе

Есть еще так много сервисов Firebase, которые мы еще не затронули. Как видите, проще создать MVP, в котором все серверные службы находятся под одной крышей. Мы установили только одну библиотеку Firebase, которая предоставляет большинство внутренних функций, необходимых большинству MVP.

Мы также не рассмотрели расширения Firebase, которые являются дополнительными функциями, которые мы можем легко реализовать для расширения нашего приложения Firebase. Примеры таких расширений включают:

Изменить размер изображений

Поиск с Алголией

Полосатые платежи

Сократить URL-адреса

И многое другое. Если вам понравился Firebase и вам нужна более мощная база данных, вы можете попробовать Supabase — альтернативу с открытым исходным кодом, предлагающую базу данных PostgreSQL. Тем не менее, Supabase является новым продуктом на рынке и на момент написания статьи находится на стадии бета-тестирования.

3D-печать5GABC-анализAndroidAppleAppStoreAsusCall-центрChatGPTCRMDellDNSDrupalExcelFacebookFMCGGoogleHuaweiInstagramiPhoneLinkedInLinuxMagentoMicrosoftNvidiaOpenCartPlayStationPOS материалPPC-специалистRuTubeSamsungSEO-услугиSMMSnapchatSonyStarlinkTikTokTwitterUbuntuUp-saleViasatVPNWhatsAppWindowsWordPressXiaomiYouTubeZoomАвдеевкаАктивные продажиАкцияАлександровск ЛНРАлмазнаяАлчевскАмвросиевкаАнализ конкурентовАнализ продажАнтимерчандайзингАнтрацитАртемовскАртемовск ЛНРАссортиментная политикаБелгородБелицкоеБелозерскоеБердянскБизнес-идеи (стартапы)БрендБрянкаБукингВахрушевоВендорВидеоВикипедияВирусная рекламаВирусный маркетингВладивостокВнутренние продажиВнутренний маркетингВолгоградВолновахаВоронежГорловкаГорнякГорскоеДебальцевоДебиторкаДебиторская задолженностьДезинтермедитацияДзержинскДивизионная система управленияДизайнДимитровДирект-маркетингДисконтДистрибьюторДистрибьюцияДобропольеДокучаевскДоменДружковкаЕкатеринбургЕнакиевоЖдановкаЗапорожьеЗимогорьеЗолотоеЗоринскЗугрэсИжевскИловайскИрминоКазаньКалининградКировскКировскоеКомсомольскоеКонстантиновкаКонтент-маркетингКонтент-планКопирайтингКраматорскКрасноармейскКрасногоровкаКраснодарКраснодонКраснопартизанскКрасный ЛиманКрасный ЛучКременнаяКураховоКурскЛисичанскЛуганскЛутугиноМакеевкаМариупольМаркетингМаркетинговая информацияМаркетинговые исследованияМаркетинговый каналМаркетинг услугМаркетологМарьинкаМедиаМелекиноМелитопольМенеджментМерчандайзерМерчандайзингМиусинскМолодогвардейскМоскваМоспиноНижний НовгородНиколаевНиколаевкаНишевой маркетингНовоазовскНовогродовкаНоводружескНовосибирскНумерическая дистрибьюцияОдессаОмскОтдел маркетингаПартизанский маркетингПервомайскПеревальскПетровскоеПлата за кликПоисковая оптимизацияПопаснаяПравило ПаретоПривольеПрогнозирование продажПродвижение сайтов в ДонецкеПроизводство видеоПромоПромоушнПрямой маркетингРабота для маркетологаРабота для студентаРазработка приложенийРаспродажаРегиональные продажиРекламаРеклама на асфальтеРемаркетингРетро-бонусРибейтРитейлРовенькиРодинскоеРостов-на-ДонуРубежноеСамараСанкт-ПетербургСаратовСватовоСвердловскСветлодарскСвятогорскСевастопольСеверодонецкСеверскСедовоСейлз промоушнСелидовоСимферопольСинергияСколковоСлавянскСнежноеСоздание сайтов в ДонецкеСоледарСоциальные сетиСочиСтаробельскСтаробешевоСтахановСтимулирование сбытаСуходольскСчастьеТелемаркетингТельмановоТираспольТорговый представительТорезТрейд маркетингТрейд промоушнТюменьУглегорскУгледарУкраинскХабаровскХарцызскХерсонХостингЦелевая аудиторияЦифровой маркетингЧасов ЯрЧелябинскШахтерскЮжно-СахалинскЮнокоммунаровскЯндексЯсиноватая