Что такое Firebase и почему стоит с этим познакомиться

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

Firebase хранит текстовые данные в JSON формате и предоставляет удобные методы для чтения, обновления и извлечения данных. Также, Firebase может помочь с регистрацией и авторизацией пользователей, хранением сессий (авторизованные пользователи), медиафайлов к которым с легкостью предоставляет доступ благодаря Cloud Storage.

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

Зачем нужна Firebase, ведь есть другие базы данных...

Единственная причина, по которой я изначально заинтересовался Firebase, это гибкость и скорость деплоя в проект.

Вот смотрите: языки программирования Python и JavaScript сами по себе гибкие (и очень популярные). Благодаря этому, мы (разработчики) получаем мощный инструмент для создания в кратчайшие сроки сайта, веб-приложения, мобильного или даже десктопного приложения.

Firebase позволяет сохранять эту скорость. Не нужно отвлекаться на какие-то другие вещи (создание базы данных, написание API приема и получения данных). Вся серверная часть ложится на плечи этого сервиса. Благодаря такому мощному инструменту можно за один вечер накидать функционал любого модуля с чтением, сохранением данных и показать заказчику функциональный пример. 

Ну а если у Вас маленькое SPA-приложение или простенькое мобильное, где все сводится к манипулированию каких-то текстовых значений, можно использовать Firebase как основную базу данных. И даже платить не надо. 

Панель управления Firebase

Переходим к практическому ознакомлению, давайте все щупать руками. Мы посмотрим, что находится внутри “Консоли разработчика” Firebase, познакомимся с интересными методами и отправим пару тестовых запросов. Примеры я буду показывать на JavaScript в проекте где используется Webpack и менеджер пакетов npm. Основа, все же, это JavaScript, поэтому не пугайтесь.

Регистрация

Сначала нужно перейти на сайт и зарегистрироваться в Firebase. Можно использовать свою Google почту для быстрой регистрации.

firebase регистрация и создание проекта

Нажимаем на большую кнопку “Добавить проект”. По желанию подключаем Google Аналитику. Возможно (не знаю осталось ли это в новой версии), вас попросит выбрать местоположение проекта, просто выберите свою страну.


панель управления firebase

Внутри консоли сегодня нас интересуют только 3 вещи: настройки проекта, база данных и аутентификация. Если моя статья Вас заинтересует, то с остальными функциями Firebase можете ознакомиться сами. Все ссылки я оставлю. Например, Storage - это хранилище медиафайлов, но с ним мы сегодня работать не будем 

Установка в проект за 60 секунд

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

конфигурация firebase для установки

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

npm install firebase --save

Если у вас Mac или Linux добавьте перед npm команду sudo. 

P.S: Если не учитывать, что пакеты будут устанавливаться около 3-4 минут, заголовок раздела полностью оправдывает себя. Ну ведь правда, за 60 секунд вполне реально подключить Firebase.

И не забудьте добавить firebase в проект.

import firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/database'
import 'firebase/storage'
import 'firebase/messaging'

Можно, конечно, просто добавить одну строчку: 

import firebase from 'firebase/app'

Но тогда вес исходного файла dist.js, который собирается с помощью webpack для prodaction версии приложения будет нереально большой. Поэтому я просто выбрал то, что мне пригодится для примера. 

Теперь вставляем код из конфигурации и запускаем метод firebase.initializeApp(), в аргумент которого складываем объект config. Все это делаем во время инициализации (начала работы) вашего приложения. Пример с моего проекта:

пример установки конфигурации в проект

Вот и все. Давайте посмотрим на полную мощь этого инструмента. Теперь можно перейти к регистрации пользователей.

Регистрация и авторизация пользователей за 5 минут

регистрация и авторизация пользователей

Для начала вернемся в консоль Firebase и перейдем на страницу “Аутентификация”. Здесь есть две вкладки, это Пользователи и Метод регистрации

Вкладка Пользователи покажет вам всех зарегистрированных пользователей в приложении. Вкладка Метод регистрации позволяет выбрать и настроить предпочтительный метод. Например, включим регистрацию по почте и паролю. По желанию можете там добавить авторизацию по ссылке пришедшей на почту. Просто нажмите на “Адрес электронной почты и пароль” и увидите необходимые настройки.

Метод firebase.auth().createUserWithEmailAndPassword()

С помощью этого метода мы создаем нового пользователя. 

const data = firebase.auth().createUserWithEmailAndPassword(email, password)

После удачной регистрации константа data будет содержать в себе данные пользователя. Например, если вывести в консоль data.user.uid, можно увидеть уникальный идентификатор, который теперь присвоен этому пользователю.

Пример кода:

async registration(email, password) {
    try {
        const data = await firebase.auth().createUserWithEmailAndPassword(email, password)
        console.log(data.user.uid)
    } catch (error) {
        console.log(error.message)
        throw error
    }
}

Я создал асинхронную функцию (если с ними не знакомы, можете прочитать статью по ссылке). В конструкции try я создаю константу data, которая ждет await метод firebase. Благодаря волшебному слову await моя async функция превращается в промис и ждет заполнения переменной data. После заполнения (удачной регистрации) она превратится в объект и будет содержать в себе данные о пользователе. Т.е потом, можно вызвать эту переменную в консоль.

Например, можно вызвать console.log(data) и получить огромный объект с кучей разных атрибутов. В моем примере, через console.log(data.user.uid), вызывается уникальный идентификатор пользователя (которого мы только что зарегистрировали).

В сам метод firebase.auth().createUserWithEmailAndPassword() я отправляю почту пользователя и будущий пароль.

В catch мы можем попытаться поймать объект error.

пример ошибок приходящих с сервера firebase

Из объекта error вы можете выдергивать сообщения или статус коды ошибок. Кстати, статус коды полезная вещь, ведь сообщения приходят на английском. Я лично обрабатываю только статус коды и вывожу через switch нужное сообщение пользователю.

Обработка ошибок из моего приложения:

пример обработки ошибок firebase

Оставлю полезную ссылку на все статус-коды ошибок у авторизации. У каждого метода свои статус коды ошибок!

Метод firebase.auth().signInWithEmailAndPassword()

Это метод авторизации. Давайте сразу на примере. Смотрим в конструкцию try.

Пример кода:

async login(email, password) {
           try {
               const data = await firebase.auth().signInWithEmailAndPassword(email, password)
               console.log(data.user.uid)
           } catch (error) {
               console.log(error.message)
               throw error
           }
       }

Все такая же async функция и await метод. В await метод firebase.auth().createUserWithEmailAndPassword() я передаю почту и актуальный пароль пользователя. 

После прохождения авторизации (успешного выполнения метода firebase.auth().createUserWithEmailAndPassword()) константа data будет содержать в себе объект user с его идентификатором. Если пароль (ну или еще что-нибудь) будет неверным, сработает метод catch и firebase ответит ошибкой.

Через catch мы как раз и ловим сообщения об ошибках от метода firebase.

Метод firebase.auth().onAuthStateChanged()

С помощью этого метода мы можем получить авторизованного пользователя. Это что-то вроде сессии. Пока сессия существует, мы можем использовать некоторые глобальные переменные Firebase. Например, получить объект user, в котором есть идентификатор авторизованного пользователя. Сама сессия существует пару дней и привязывается к ip адресу (но это не точно).

Пример кода:

firebase.auth().onAuthStateChanged(user => {
  if (user) {
    // Какая-то логика
  } else {
    this.$router.push('/login')
  }
})

Как видите, если user существует - я что-то делаю с этим. Если нет, отправляю человека на страницу авторизации с помощью методов из Vue.js.

Ну что, впечатлены? Если бы вы это делали второй или третий раз, то потратили не больше 10 минут на полноценную регистрацию и авторизацию пользователей.

Чтение, запись и обновление данных

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

Почему Realtime Database?

Потому что она старше, стабильней и почти любая проблема с ней освещена в интернете.

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

Возвращаемся к работе с данными

Чтобы контекст был понятен, так выглядит моя база на данный момент:

пример базы данных firebase

Метод firebase.database().ref().push()

Для записи данных в Firebase используем метод firebase.database().ref().push().

Пример кода:

async newClient(newClinet) {
           try {
               const addClient = await firebase.database().ref('clients').push(newClinet)
               console.log(addClient)
           } catch (error) {
               console.log(error.message)
               throw error
           }
       }

Нам нужно создать асинхронную функцию. К методу firebase мы добавляем await. Если дальше хотим как-то обработать ответ от базы данных асинхронные функции обязательны.

Здесь в асинхронной функции newClient я передаю аргумент newClient. Данный аргумент содержит какой-то объект с данными, далее этот объект (новый клиент) я отправляю в Firebase.

Метод ref() содержит в себе путь, куда мы будем что-то добавлять. Для более детального понимания смотрите скриншот выше, там копия моей базы. Данного пути еще может даже не существовать, поэтому с помощью этого метода можно создавать новые хранилища (объекты в json хранилище).

Метод push() содержит в себе данные, которые мы будет отправлять в объект clients. 

Представим, код выше я запустил 3 раза. Результат запросов вы можете увидеть все на том же скриншоте выше. Как видите Firebase сама создала главный объект (хранилище) clients и записала в него три объекта поменьше. Каждому объекту Firebase сгенерировала свой ключ (идентификатор). Он уникален в рамках объекта clients.

Метод firebase.database().ref().once()

Для получения данных из Firebase используем метод firebase.database().ref().once(). 

Пример кода:

async loadClietsList() {
           try {
               const query_clientsList = await firebase.database().ref('clients').once('value')
               const clientsList = query_clientsList.val()         
               console.log(clientsListArray)
           } catch (error) {
               console.log(error.message)
               throw error
           }
       }

Нам нужно также создать асинхронную функцию. Методу firebase мы добавляем await. Константа query_clientsList содержит в себе вышеописанный метод. В ref указывается путь к объекту, который хотим получить. Посмотрите на скриншот выше, clients у меня находятся в основе моей базы данных, поэтому путь выглядит у меня максимально простым.

Если я хочу обратиться к какому-то клиенту из clients в ref, я укажу еще его идентификатор, получится ref(‘clietns/-M5mvz6HSFnbP3L2KiHG’), а если я хочу взять номер телефона конкретного клиента, ref будет выглядеть так ref(‘clietns/-M5mvz6HSFnbP3L2KiHG/number’).

После ref идет обязательный метод once(‘value’). Т.е мы говорим Firebase, что хотим по этой ссылке получить какие-то значение.

Когда await выполнится, и константа query_clientsList заполнится, мы можем воспользоваться методом val() по отношению к константе. Например, query_clientsList.val(). Если эту конструкцию мы попробуем отправить в консоль, то увидим заветные данные: три клиента из моей базы данных.

Метод firebase.database().ref().remove()

Данный метод отвечает за удаление данных из нужного объекта.

Пример кода:

firebase.database().ref('clients').remove()

Такая команда полностью удалит весь объект clients.

Если путь у ref() будет примерно такой: 'clients/-M5mvz6HSFnbP3L2KiHG’, то удален будет только тот объект в clients, который имеет данный идентификатор.

Права доступа

В базе данных есть вкладка “Правила”. 

пример настройки прав доступа для firebase базы данных

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

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

В правах доступа используется свой “язык” оперирующий значениями true и false. На скриншоте выше мои настройки, здесь я просто запретил чтение и запись всем, кто не авторизован. Мое приложение это обычная CRM система для малого бизнеса, у нее общее хранилище и данными внутри управляют 3-4 человека, а свободная регистрация вообще отсутствует, поэтому таких настроек хватает. 

Ваше приложение - ваша логика, поэтому позаботьтесь о безопасности.

P.S: Как и обещал, ссылка на документацию к Storage.

Вывод

Надеюсь, вы впечатлены мощью инструмента Firebase и обязательно с ним ознакомитесь хотя бы в тестовых целях.

Опубликовано: 2020-05-04 16:45