Firebase – это облачный сервис, сочетающий в себе множество функций: аутентификацию, базу данных в реальном времени, хранение файлов, уведомления и прочее. В этой статье мы главным образом рассмотрим базы данных и немного аутентификацию. Главная цель – собрать всю необходимую информацию об использовании Realtime баз данных, потому что всегда лучше иметь все в одном месте.
Я объединил всю полезную информацию в девять советов, и вот они.
Совет 1
При создании модели базы данных для приложения, постарайтесь использовать как можно меньше вложенных объектов.
Например:
{ // Это плохая архитектура данных, потому что нужно будет итерирование дочерних // узлов чатов для получения списка диалогов, что потенциально // потребует загрузки, возможно, сотен мегабайтов сообщений "chats": { "one": { "title": "Первопроходцы технологий", "messages": { "m1": { "отправитель": "гхоппер", "сообщение": "Неисправность найдена. Причина: мотылек" }, "m2": { ... }, // очень длинный список сообщений } }, "two": { ... } } }
Даже если вам нужен просто один заголовок, все остальные данные будут также получены вместе с ним. Это может увеличить время получения данных.
Совет 2
Дублирование некоторых полей нормально для Firebase – когда один объект имеет свойства другого. Однако лучше продублировать одно поле вместо создания связей между двумя объектами, следовательно, сделать один запрос вместо двух.
Совет 3
Общение между базой данных Firebase и клиентом производится путем подключения пользователей к узлам баз данных. Обратите внимание, что когда вы свяжете пользователя с определённым узлом, он сразу получит данные. Так что вам надо игнорировать первое срабатывание в случае, если вы просто хотите “слушать” обновление ноды.
Совет 4
Если необходимо прочитать список объектов из узла, вы должны перебирать дочерние объекты снапшота и читать объекты один за другим. Например:
public void onDataChange(DataSnapshot dataSnapshot) { List deliveries = new ArrayList<>(); for(DataSnapshot snapshot : dataSnapshot.getChildren()){ Foo foo = snapshot .getValue(Foo.class); deliveries.add(foo); } }
Совет 5
При чтении объекта и создании Java-класса, вам следует следовать определенным условиям (в определении полей объектов):
- В Java-классе должен быть пустой конструктор.
- Названия полей класса должны быть такими же, как и названия полей объекта.
- Для каждого класса должен быть метод получения данных.
Если эти условия не будут соблюдены, данные нельзя будет парсить.
Совет 6
При использовании аутентификации необходимо проверить, существует ли пользователь и верны ли введенные параметры аутентификации. Вы можете использовать исключения:
public void onComplete(@NonNull Task task) { if ( !task.isSuccessful() ) { try { throw task.getException(); } catch(FirebaseAuthInvalidUserException e) { // No such user } catch(FirebaseAuthInvalidCredentialsException e) { //Credentials are invalid } catch(Exception e) { e.printStackTrace(); } return; } }
Совет 7
Firebase плохо фильтрует данные. Например, вы можете сделать запрос, основанный только на одном условии, но вы не можете сделать запрос типа “WHERE… AND… AND”. В этой ситуации необходимо создать одно дополнительное поле в объекте, которое будет содержать значения, и выборка будет проходить с использованием этого значения. Например:
"movie1": { "genre": "комедия", "name": "Лучше не бывает", "lead": "Джек Николсон", "genre_lead": "комедия_Джек Николсон" },...
Используя эту структуру, мы можем найти комедию с Джеком Николсоном в главной роли.
Совет 8
В Firebase нет ролей. Все аутентифицированные аккаунты будут определяться только email-ом, паролем и универсальным идентификатором. Но мы можем назначить роли с помощью базы данных.
Совет 9
Если у вашего объекта в Firebase есть вложенный объект, который может быть пустым в некоторых случаях, лучше удалить этот объект полностью вместе с ключом вместо того, чтобы сохранять его ключ с пустым значением. Причиной этого является то, что парсер данных на стороне устройства может работать с определенным типом, и если этот тип будет отличаться от существующего, произойдет ошибка. Если объекта не будет, результат анализа вернется пустым.
Например:
//Водитель внес данные об автомобиле "driver": { "car": { "model": "Audi TT", "vin": "KL5TJ66E19B411947", }, "first_name": "John", "last_name": "Doe" },... //Водитель не внес данные об автомобиле //Плохой пример "driver": { "car": "", "first_name": "John", "last_name": "Doe" },... //Хороший пример "driver": { "first_name": "John", "last_name": "Doe" },...
Как вы видите, в неправильном примере у парсера будет объект driver с вложенным объектом car, но на самом деле тип будет String.
Я бы хотел подчеркнуть, что в общем опыт моего использования Firebase положителен. Но как и всё в нашем мире, он имеет свои плюсы и минусы.
Плюсы Firebase
Во-первых, база данных в реальном времени – это очень хорошая альтернатива серверу при создании несложных приложений, потому что в ней есть все необходимое. И, без сомнения, большой плюс – система callback-ов при получении данных. Когда что-то меняется в базе данных, ответное действие на стороне устройства срабатывает сразу же. Отлично, да?
Минусы Firebase
Нет замены старому доброму RESTful. Да, у него нет динамического обновления данных, но можно использовать базу данных SQL, которая значительно лучше NoSQL, которая используется в Firebase. Также в нем можно сделать сложную систему логинов. И помните, что у Firebase есть ограничения для бесплатных аккаунтов. Если вы хотите хранить большое количество данных в базе или зарегистрировать больше одного проекта в одном аккаунте, то вы должны будете заплатить.