воскресенье, 27 марта 2016 г.

Руководство по Firebase: создаем приложения с помощью Firebase



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

Это руководство поможет вам понять некоторые из ключевых концепций Firebase и его API. Мы  создадим простой инструмент в режиме реального времени для аналитики , который будет отображать метрики нашего сайта и то что наши посетители просматривали в реальном времени. Весь наш код на JavaScript будет работать только в веб-браузере, но Firebase поддерживает множество других языков и сред, в том числе Node.js, Objective-C (IOS / OS X), Java (Android). Она также обеспечивает REST API, так что вы можете читать и записывать данные с любого сервера, даже если у вас нет официальной поддержки SDK. Мы будем использовать JQuery для обновления DOM в нашей аналитической инструментальной панели.



Концепции Firebase

Firebase использует модель, управляемую событиями, чтобы уведомить нас об изменениях в наших данных, а также предоставить данные, когда они впервые приходят. Вы должны быть знакомы с событийно - ориентированным программированием, если вы использовали Node.js раньше, мы еще раз рассмотрим это , поскольку эта методология существенно отличается от традиционной модели запрос-ответ(request-reply) , которую большинство приложений используют в наше время. В модели запрос-ответ, ваше приложение отправляет данные за пределы на ваш сервер. Сервер может взаимодействовать с SQL (или NoSQL) базами данных и, возможно, даже внешним API, прежде чем ответить на ваш клиент с запрошенными данными . После того, как ответ получен, обмен на этом заканчиваеться. Клиентское приложение всегда знает, когда он будет получать новые данные, потому что оно всегда должен явно запросить его, прежде чем что-либо будет получено.

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

function logVisitorCount (snapshot) {
  console.log('There are currently ', snapshot.val(), ' visitors on the site');
}
totalVisitors.on('value', logVisitorCount);


totalVisitors представляет собой ссылку Firebase, также слушатель для события для  'value' используя метод on для передачи обратного вызова(callback) logVisitorCount.
API Firebase JavaScript будет вызывать нашу функцию logVisitorCount  каждый раз, когда 'value'  расположенное в  totalVisitors будет изменяться .
В своей сути, БД Firebase это просто большой объект в формате JSON. Где нет таблиц. Где нет даже аналогов коллекций и документов из MongoDB.
Вы можете организовать данные как вам угодно,  изменять схему в любое время, и делать вложенные объекты и значения так глубоко, как вы хотите. Это становится чрезвычайно ценно, когда вы  моделируете приложения. Вот схема которую мы будем использовать для нашего приложения аналитики, в том числе данные выборки:

{
  "totalVisitors": 5,
  "activeVisitors": {
    "-IKo28nwJLH0Nc5XeFmj": {
      "path": "/",
      "arrivedAt": 1413392152630,
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 
(KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36"
    }
  },
  "pastVisitors": {
    "-INOQPH-aV_psbk3ZXEX": {
      "path": "/",
      "arrivedAt": 1413392151219,
      "leftAt": 1413392155419,
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36"
    }
  }
}
Вы заметили, что значения ключей для activeVisitors и pastVisitors имеют длинные рандомизированные имена.
Это потому, что Firebase не может использовать традиционные массивы с числовыми ключами или же мы би создали колизии
отменим присвоение. Взгляните на простой пример:
//ref = ['Foo'];
ref.push ('bar');
В то же время, другой клиент вызывает
ref.push('baz');
Что случилось? Если мы будем использовать традиционные массивы JavaScript с помощью числовых ключей,
оба клиенты будут пытаются записать данные в ref[1]. Тот, кто получает доступ к серверу последним тот перезапишет данные,
полученные ранее. Мы, же конечно, не хотим этого. Вместо того чтобы использовать массивы, коллекции упорядоченных данных в
Firebase представлены объектами с автоматически сгенерированных ключей, которые выглядят как "-IKo28nwJLH0Nc5XeFmj".
Эти ключи генерируются автоматически и кодируют как временную метку так и уникальный ID клиента.
Таким образом, несколько клиентов могут записывать данные одновременно с коллизиями и
ваши данные будут по-прежнему будут возвращены в порядке.

Начало работы
Что начать работать с Firebase нужно создать учетную запись. План "Hacker" на сайте бесплатен для 50 подключений к бд, 100 Мб для хранения и 5 Гб для трафика.  При создании первой базы данных, вам будет предоставлен Forge, это веб-интерфейс Firebase для просмотра и редактирования данных, а также изменения параметров базы данных.

Мы собираемся создать два основных компонента: код для передачи наших данных аналитики к Firebase и  простой панели управления, чтобы потом прочитать наши данные. Наш проект будет выглядеть следующим образом:
analytics.js
dashboard.js
dashboard.html
sample-page/
 index.html

Запись в Firebase

Когда пользователь открывает нашу страницу, мы хотим, сохранить время посещения, узнать адрес откуда он пришел, и  user agent в нашем списке активных посетителей.
Нам нужно создать ссылку на нашу коллекцию activeusers, прежде чем мы сможем сохранить их. Чтобы создать новую Firebase ссылку, мы сделаем следующее:

var analytics = new Firebase('https://airpair-analytics-tutorial.firebaseio.com/');

Вы можете скопировать и вставить путь непосредственно из Firebase Forge.
Мы могли бы создать ссылку непосредственно для наших activeusers, как здесь:

var activeUsers = new Firebase('https://airpair-analytics-tutorial.firebaseio.com/activeUsers');

Так как мы хотим записывать данные и других местах в нашей базе,
мы будем использовать метод child вместо того, чтобы сохранить нашу корневую ссылку, но и ссылки на данные activeusers :
var analytics = new Firebase('https://airpair-analytics-tutorial.firebaseio.com/');
var activeVisitors = analytics.child('activeVisitors');

Теперь мы можем отправлять наши данные о пользователях, когда они приходят, используя метод push:

activeVisitors.push({
  path: window.location.pathname,
  arrivedAt: Firebase.ServerValue.TIMESTAMP,
  userAgent: navigator.userAgent
});

Вы заметили, что вместо Date.now(), мы используем Firebase.ServerValue.TIMESTAMP в arrivedAt для создания метки времени.
Это значение будет заменено Firebase, когда он получает данные с меткой времени с сервера.
Таким образом, даже если часы всех наших клиентов установлены неправильно, наши данные будут всегда
находиться в правильном порядке.

Установка analytics.js

Переход к sample-page/index.html, давайте добавим теги сценария мы должны записать данные в Firebase до конца тега нашего документа:




<script src="https://cdn.firebase.com/js/client/1.1.1/firebase.js"></script>
<script src="../analytics.js"></script>

Теперь мы можем открыть нашу страницу в браузере рядом с Firebase Forge и смотреть на данные посетителей которые  будут записаны на Firebase каждый раз мы обновляем страницу.

Чтение из Firebase
Теперь, когда мы сделали скрипт аналитики , который можна встраивать на нашем сайте, мы можем начать отображать некоторые данные, которые мы собрали в реальном времени. Сначала мы создадим наш файл dashboard.html с некоторыми пустыми элементами, которые мы можем начать заполнять с нашими данными. Наш HTML будет выглядеть следующим образом:


<section>
  Total Visitors: <span id="total-visitors"></span>
</section>
<section>
  Active Visitors
  <ul id="active-visitors"></ul>
</section>
<section>
  Past Visitors
  <ul id="past-visitors"></ul>
</section>
<script src="https://cdn.firebase.com/js/client/1.1.1/firebase.js"></script>
<script src="https://code.jquery.com/jquery-2.1.1.js"></script>
<script src="./dashboard.js"></script>

Обновление значений
Привязка данных(data binding) как в Angular или Backbone тоже здесь используеться.
Для простоты, мы будем управлять нашими элементами DOM вручную в этом руководстве. Мы используем JQuery для удобства. Сейчас мы будем работать в dashboard.js .

Давайте сначала обновим общее число посетителей , что бы представляло только одно значение.
$(document).on('ready', function () {
  var $totalVisitors = $('#total-visitors');
  analytics.child('totalVisitors').on('value', function (snapshot) {
    $totalVisitors.text(snapshot.val());
  });
});

Работа с запросами
Если вы привыкли к SQL, вы можете быть удивлены, как здесь фильтруются данные. У вас нет такой же гибкости, что и при работе с SQL, где есть условия выборки , но Firebase предусматривает несколько методов для ограничения получаемых данных. Мы рассмотрим их очень кратко, но знайте, что запросы в Firebase может быть довольно мощным, если вы уммете их использовать .

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

var pastVisitors = analytics.child('pastVisitors').endAt().limit(3);
pastVisitors.on('child_added', function (snapshot) {
 // ...
});

Вы заметите, что для этого требуется лишь небольшое изменение в одной строке кода.
Мы вызовем, endAt () на что бы сообщить Firebase что  мы хотим выполнить наш запрос в конце нашего набора данных, затем вызовем  limit(3), чтобы ограничить наш запрос до 3 записей.


2 комментария: