Цель Firebase — помочь разработчикам создавать лучшие приложения и развивать их в успешном бизнесе. Заботясь о бэкэнде или инфраструктуре вашего приложения, Firebase позволяет вам сосредоточиться на решении проблем ваших пользователей. Одна из новых интересных функций, анонсированных на конференции Google Cloud Next ’17 в марте этого года для Firebase, была Cloud Functions . В этом руководстве вы узнаете об этой новой функции, создав с ее помощью простое приложение для Android.
Что такое облачные функции для Firebase?
Облачные функции Firebase работают в размещенной, частной и масштабируемой среде Node.js, где вы можете запускать код JavaScript. Вы просто создаете реактивные функции, которые запускаются всякий раз, когда происходит событие. Облачные функции доступны как для Google Cloud Platform, так и для Firebase (они были созданы поверх облачных функций Google).
На данный момент облачные функции поддерживают следующие триггеры, которые вы можете прослушивать и реагировать на них:
- Триггеры базы данных реального времени : запускают функцию, когда происходит событие записи на пути в базе данных.
- Триггеры аутентификации : запускают функцию при создании нового пользователя или при удалении пользователя.
- Триггеры аналитики : запускают функцию, когда регистрируется новое событие преобразования.
- Триггеры облачного хранилища : функция может быть запущена при любых изменениях в корзине, таких как загрузка, обновление или удаление файла или папки.
- Cloud Pub / Sub Trigger : запуск функции при получении нового сообщения в теме Google Cloud Pub / Sub.
- Триггеры HTTPS : срабатывает, когда запрос сделан к конечной точке.
Так зачем использовать облачные функции?
Итак, теперь вы увидели ряд возможностей, которые могут предложить облачные функции. Но зачем их использовать?
Запуск и настройка серверной части и серверов могут быть настоящей проблемой — вам приходится решать такие проблемы, как масштабируемость и написание кода на серверных языках, — но с помощью облачных функций эта сложность уменьшается. Кроме того, вычислительные задачи могут выполняться в облаке, а не на клиентском устройстве (например, изменение размера изображения для загрузки или записи в несколько путей вашей базы данных). Ваш код также будет более безопасным в облаке, чем на клиентском устройстве, поэтому вы можете безопасно хранить такие данные, как секретные ключи на вашем сервере.
В этом руководстве вы узнаете, как использовать триггеры базы данных реального времени, которые срабатывают при возникновении события записи в базу данных. Затем мы увидим, как использовать службу Firebase Cloud Messaging для отправки уведомлений на устройства, которые подписались на тему. Мы создадим простое приложение под названием Tutsplus Alerts , которое будет отправлять уведомление подписчикам темы «android» всякий раз, когда будет доступна новая статья.
Предпосылки
Чтобы следовать этому уроку, вы должны быть знакомы с:
И у вас должен быть установлен Node.js на вашем компьютере.
Посмотрите следующие уроки здесь на Envato Tuts +, если вам нужна помощь для начала работы с Firebase:
-
Android SDKНачните с Firebase для Android
-
FirebaseFirebase для Android: уведомления и приглашения приложений
-
Android SDKНачните с Firebase для Android
1. Создайте облачную функцию Firebase
Установите Firebase CLI
Теперь, когда предварительные условия настроены, давайте загрузим облачные функции.
Чтобы начать использовать облачные функции, нам нужен Firebase CLI ( интерфейс командной строки), установленный с npm . Если на вашем компьютере уже настроен Node, вы можете установить Cloud Functions с помощью:
1
|
npm install -g firebase-tools
|
Эта команда установит интерфейс командной строки Firebase вместе со всеми необходимыми зависимостями Node.js.
Инициализировать проект
Чтобы инициализировать ваш проект:
- Запустите
firebase login
чтобы войти в Firebase через браузер и аутентифицировать инструмент CLI. - Создайте новый каталог проекта с именем tutsplus -alerts .
- Наконец, запустите
firebase init functions
из этого нового каталога. Этот инструмент дает вам возможность установить зависимости с помощью NPM. Отказаться безопасно, если вы хотите управлять зависимостями другим способом.
После успешного выполнения этих команд структура вашего проекта выглядит следующим образом:
- .firebaserc : скрытый файл, который помогает вам быстро переключаться между проектами с
firebase use
. - firebase.json : описывает свойства для вашего проекта.
- functions / : эта папка содержит весь код для ваших функций.
- functions / package.json : файл пакета NPM, описывающий ваши облачные функции.
- functions / index.js : основной источник кода вашего Cloud Functions.
- functions / node_modules / : папка, в которой установлены все ваши зависимости NPM.
Импортируйте необходимые модули и инициализируйте приложение
Для разработки нашего простого приложения Tutsplus Alerts нам просто нужны два модуля узлов: модули облачных функций и Admin SDK (эти модули уже установлены для нас). Поэтому перейдите в index.js и потребуйте эти модули, а затем инициализируйте экземпляр приложения администратора.
1
2
3
4
|
var functions = require(‘firebase-functions’);
var admin = require(‘firebase-admin’);
admin.initializeApp(functions.config().firebase);
|
Кодирование функции облака
Теперь, когда необходимые модули для нашего проекта были импортированы и инициализированы, давайте закодируем нашу облачную функцию в файле index.js . Как указывалось ранее, мы напишем функцию, которая будет onWrite()
при возникновении onWrite()
в нашей базе данных реального времени Firebase, а затем в ответ отправит уведомление (нисходящее сообщение) подписчикам устройства.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
// …
exports.sendNotification = functions.database.ref(‘/articles/{articleId}’)
.onWrite(event => {
// Grab the current value of what was written to the Realtime Database.
var eventSnapshot = event.data;
var str1 = «Author is «;
var str = str1.concat(eventSnapshot.child(«author»).val());
console.log(str);
var topic = «android»;
var payload = {
data: {
title: eventSnapshot.child(«title»).val(),
author: eventSnapshot.child(«author»).val()
}
};
// Send a message to devices subscribed to the provided topic.
return admin.messaging().sendToTopic(topic, payload)
.then(function (response) {
// See the MessagingTopicResponse reference documentation for the
// contents of response.
console.log(«Successfully sent message:», response);
})
.catch(function (error) {
console.log(«Error sending message:», error);
});
});
|
В приведенном выше коде мы слушаем путь к базе данных /articles/{articleId}
, где {articleId}
представляет идентификатор статьи, которая была успешно написана. Теперь, что нас действительно беспокоит, так это данные, которые были написаны. Чтобы получить это, мы используем event.data
, который является статическим интерфейсом DeltaSnapshot .
Затем добавьте данные из этого снимка в полезную нагрузку сообщения и отправьте их в раздел «Android». Асинхронный код упрощается обещаниями JavaScript .
Обратите внимание, что в приведенном выше коде мы написали в консоль с помощью console.log()
, который поможет нам в отладке и мониторинге. Мы можем просмотреть этот журнал либо на нашей панели инструментов Firebase, либо через командную строку:
1
|
firebase functions:log
|
Имейте в виду, что, поскольку это выполняется на Node.js, вы можете установить другие модули, доступные из NPM. Вы также можете кодировать в JavaScript ES6 или TypeScript вместо обычного JavaScript.
Разверните облачную функцию
Давайте развернем нашу облачную функцию. Запустите эту команду для развертывания:
1
|
$ firebase deploy —only functions
|
Теперь мы можем кодировать приложение для Android, которое будет подписываться на эту тему, записывать в базу данных в реальном времени и получать уведомление, когда данные записываются в нашу базу данных в реальном времени, то есть когда будет выполняться наша облачная функция!
2. Создайте приложение TutsplusAlerts
Создать проект Android Studio
Сначала запустите Android Studio и создайте новый проект TutsplusAlerts с пустым действием MainActivity
.
Чтобы следовать этому, убедитесь, что вы интегрировали Firebase в свое приложение .
Добавьте зависимость базы данных в реальном времени
Добавьте следующую зависимость в ваш файл build.gradle :
1
|
compile ‘com.google.firebase:firebase-database:10.2.1’
|
Убедитесь, что вы синхронизируете свой проект после его добавления.
Создать модель
Давайте смоделируем объект статьи для сохранения в нашей базе данных в реальном времени.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public class Article {
public String title;
public String author;
public Article() {
// Default constructor required for calls to DataSnapshot.getValue(Article.class)
}
public Article(String title, String author) {
this.title = title;
this.author = author;
}
}
|
Создать макет XML
Наш XML-макет для основного Activity будет иметь только два EditTexts
и просто кнопку, которая представит новую статью.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<?xml version=»1.0″ encoding=»utf-8″?>
<LinearLayout
xmlns:android=»https://schemas.android.com/apk/res/android»
xmlns:tools=»http://schemas.android.com/tools»
xmlns:app=»http://schemas.android.com/apk/res-auto»
android:layout_width=»match_parent»
android:layout_height=»match_parent»
tools:context=»com.chikeandroid.tutsplusalerts.MainActivity»
android:orientation=»vertical»>
<EditText
android:id=»@+id/et_title»
android:layout_width=»match_parent»
android:layout_height=»wrap_content»
android:hint=»Title»/>
<EditText
android:id=»@+id/et_author»
android:layout_width=»match_parent»
android:layout_height=»wrap_content»
android:hint=»Author»/>
<Button
android:id=»@+id/btn_submit»
android:layout_width=»match_parent»
android:layout_height=»wrap_content»
android:hint=»Submit»/>
</LinearLayout>
|
Написать в базу данных в реальном времени
Теперь мы собираемся написать путь к базе данных в реальном времени /articles/
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// …
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final FirebaseDatabase database = FirebaseDatabase.getInstance();
final EditText titleEditText = (EditText)findViewById(R.id.et_title);
final EditText authorEditText = (EditText)findViewById(R.id.et_author);
Button submitButton = (Button)findViewById(R.id.btn_submit);
submitButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DatabaseReference myRef = database.getReference(«articles»).push();
Article article = new Article(titleEditText.getText().toString(),
authorEditText.getText().toString());
myRef.setValue(article);
}
});
}
//…
|
Вашему приложению потребуется доступ на запись в базу данных. Только для демонстрационных целей вы можете установить свои Правила безопасности, разрешающие все операции чтения и записи. В реальном приложении вы никогда не захотите использовать такие небезопасные настройки безопасности.
1
2
3
4
5
6
|
{
«rules»: {
«.read»: «true»,
«.write»: «true»
}
}
|
Вы можете узнать больше о Правилах безопасности Firebase в моем посте здесь на Envato Tuts +.
Запустите приложение
На этом этапе мы можем протестировать приложение и посмотреть, была ли наша облачная функция выполнена успешно. Введите название и автора, а затем нажмите кнопку «Отправить». После этого посетите панель инструментов « Функции» и просмотрите журналы. Наш пользовательский журнал должен появиться.
Из журналов выше мы видим, что мы успешно выполнили нашу облачную функцию и отправили сообщение с полезной нагрузкой на устройства, подписанные на тему « android », но ни одно устройство еще не подписалось на эту тему. В следующем разделе мы будем использовать Firebase Cloud Messaging, чтобы устройства могли подписаться на тему, а затем обработать входящее сообщение с сервера, чтобы отобразить уведомление.
3. Добавить поддержку Firebase Cloud Messaging
Включить зависимость
Включите зависимость Firebase Messaging в файл build.gradle и синхронизируйте ваш проект после этого:
1
|
compile ‘com.google.firebase:firebase-messaging:10.2.1’
|
Обработка сообщений
Нам нужно создать сервис, который расширяет FirebaseMessagingService и переопределяет onMessageReceived
вызовы onMessageReceived
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
package com.chikeandroid.tutsplusalerts;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
showNotification(remoteMessage.getData().get(«title»), remoteMessage.getData().get(«author»));
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
}
}
private void showNotification(String title, String author) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle(«New Article: » + title)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText(«By » + author)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
|
В приведенном выше коде мы также получаем полезную нагрузку данных и показываем ее в уведомлении независимо от того, находится ли приложение в переднем или фоновом состоянии.
Обновите файл манифеста
Обновите файл манифеста, включая службу, созданную ранее внутри <application>
.
1
2
3
4
5
6
7
8
|
//..
<service
android:name=».MyFirebaseMessagingService»>
<intent-filter>
<action android:name=»com.google.firebase.MESSAGING_EVENT»/>
</intent-filter>
</service>
//…
|
Подписаться на тему
Наконец, нам нужно подписаться на тему « android », чтобы устройство могло получать и обрабатывать сообщения, отправленные в эту тему.
1
2
3
4
5
6
7
8
|
/…
@Override
protected void onCreate(Bundle savedInstanceState) {
// …
FirebaseMessaging.getInstance().subscribeToTopic(«android»);
// …
}
//…
|
Запустите приложение
Запустите приложение во второй раз и введите название и автора, а затем нажмите кнопку «Отправить». На этот раз уведомление будет отображаться всякий раз, когда какой-либо пользователь приложения публикует в базе данных новую статью.
Чтобы сделать это до Cloud Functions, вам понадобится сервер HTTP или XMPP, который будет означать больше кода для записи, а также сервер для настройки и поддержки.
Вывод
В этом руководстве вы узнали о облачных функциях для Firebase: что они из себя представляют, зачем они вам нужны и как начать использовать облачные функции для вашего приложения. Помните, что облачные функции для Firebase все еще находятся в публичной бета-версии на момент написания этой статьи.
Чтобы узнать больше об облачных функциях для Firebase, обратитесь к официальной документации . А пока, ознакомьтесь с некоторыми другими нашими курсами и учебными пособиями по разработке приложений для Android!