Russian (Pусский) translation by Masha Kolesnikova (you can also view the original English article)
NativeScript является основой для создания кросс-платформенных нативных мобильных приложений с использованием XML, CSS и JavaScript. В этой серии мы изучаем некоторые интересные вещи, которые вы можете сделать с помощью приложения NativeScript: геолокация и интеграция с Google Maps, база данных SQLite, интеграция с Firebase и push-уведомления. По пути мы создаем фитнес-приложение с возможностями реального времени, которые будут использовать каждую из этих функций.
В этом уроке вы узнаете, как легко добавлять push-уведомления к вашему NativeScript-приложению с помощью Firebase Cloud Messaging Service
Что вы будете создавать
Исходя из предыдущего учебника, вы будете добавлять push-уведомления в приложение. Уведомление будет инициировано, когда пользователь побьет свою текущую запись или когда один из его друзей заберет у него первое место.
Настройка проекта
Если вы следовали предыдущему руководству по Firebase, вы можете просто использовать тот же проект. В противном случае вы можете создать новый проект и скопировать файлы в папку приложения вашего проекта.
tns create fitApp --appid "com.yourname.fitApp"
После этого вам также необходимо установить плагины геолокации, Google Maps, SQLite и Firebase:
tns plugin add nativescript-geolocation tns plugin add nativescript-google-maps-sdk tns plugin add nativescript-sqlite tns plugin add nativescript-plugin-firebase
После установки вам необходимо настроить плагин Google Maps. Вы можете найти полные инструкции о том, как это сделать, прочитав раздел «Установка плагина Google Maps» в предыдущем учебнике.
Затем установите библиотеку fecha для форматирования дат:
npm install --save fecha
После этого вам также необходимо настроить плагин Firebase. Обязательно прочтите следующие разделы в предыдущем учебнике, чтобы вы могли запустить приложение:
- Запуск проекта
- Настройка приложения Firebase
- Настройка приложения Facebook
- Установка плагина Firebase
- Настройка интеграции с Facebook
Поскольку мы уже создали плагин Firebase в предыдущем учебнике, для настройки push-уведомлений нужно выполнить лишь небольшую работу.
Во-первых, вы должны перенастроить плагин, перейдя в каталог node_modules/nativescript-plugin-firebase и запустив npm run config
. На этот раз выберите аутентификацию Facebook и Messaging.
Как только это будет сделано, откройте файл firebase.nativescript.json в корневой директории вашего проекта и убедитесь, что для messaging
установлено значение true
:
{ "using_ios": false, "using_android": true, "remote_config": false, "messaging": true, "crash_reporting": false, "storage": false, "facebook_auth": true, "google_auth": false, "admob": false, "invites": false }
Затем откройте app/App_Resources/Android/AndroidManifest.xml и добавьте следующие службы внутри <application>
. Это включает службу сообщений Firebase для приложения:
<application ...> <service android:name="org.nativescript.plugins.firebase.MyFirebaseInstanceIDService"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/> </intent-filter> </service> <service android:name="org.nativescript.plugins.firebase.MyFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service> </application>
Запуск проекта
Вы можете запустить проект, выполнив команду tns run android
. Но поскольку это приложение будет основываться на функциональности геолокации, я рекомендую вам использовать эмулятор GPS для быстрой настройки и изменения вашего местоположения. Вы можете прочитать о том, как это сделать в разделе «Запуск приложения» в предыдущем учебнике.
Если вы получаете какие-либо ошибки сборки, вы можете удалить платформу и повторно запустить приложение:
tns platform remove android tns run android
Настройка Firebase Cloud Functions
Вы будете использовать Firebase Cloud Functions для создания сервера, который будет отправлять push-уведомления. Эта функция Firebase используется для запуска внутреннего кода всякий раз, когда определенное событие происходит в функциях Firebase, которые вы используете, например, если в базе данных реального времени есть новые данные или когда появляется новый пользователь через службу аутентификации Firebase. Для этого приложения вы будете использовать HTTP-триггеры для отправки push-уведомлений, когда мобильное приложение делает запрос к определенной точке входа.
Чтобы использовать Firebase Cloud Functions, сначала необходимо глобально установить пакет firebase-tools
:
npm install -g firebase-tools
Затем создайте новую папку, в которой будет размещен код сервера. Это должно быть вне папки вашего приложения. Внутри этой папки установите пакет firebase-functions
:
npm install firebase-functions@latest --save
Как только он будет установлен, войдите в Firebase, выполнив команду firebase login
. Откроется новая вкладка браузера, в которой вы сможете войти в свою учетную запись Google. Пройдите весь процесс и согласитесь со всеми запрошенными разрешениями.
После входа в систему вы можете теперь инициализировать функции Firebase для конкретного проекта Firebase:
firebase init functions
Он спросит вас, хотите ли вы настроить проект по умолчанию или нет. Выберите проект Firebase, который вы создали в предыдущем учебнике:

Затем вас спросят, хотите ли вы установить зависимости. Скажи да.
После установки всех зависимостей вы должны увидеть файл firebase.json и папку с functions внутри каталога. Файл, над которым вы будете работать, - это файл functions/index.js. Откройте этот файл, и вы увидите следующее:
const functions = require('firebase-functions'); // // Create and Deploy Your First Cloud Functions // // https://firebase.google.com/docs/functions/write-firebase-functions // // exports.helloWorld = functions.https.onRequest((request, response) => { // response.send("Hello from Firebase!"); // });
Раскомментируйте функцию helloWorld
, и вы увидите триггеры HTTP в действии.
exports.helloWorld = functions.https.onRequest((request, response) => { response.send("Hello from Firebase!"); });
Для развертывания функции в облаке выполните следующее:
firebase deploy --only functions
По завершении развертывания он должен показать URL-адрес, где была развернута функция:

Получите доступ к этому URL из своего браузера, чтобы увидеть результат «Привет от Firebase!».
Добавление кода сервера
Теперь вы готовы добавить код для внедрения push-уведомлений. Во-первых, вы добавите код для серверного компонента, а затем код для приложения.
Откройте файл functions/index.js и очистите его содержимое.
Создание функции Firebase
Импортируйте пакеты Firebase, которые вам понадобятся:
const functions = require('firebase-functions'); // for listening to http triggers const admin = require('firebase-admin'); // for accessing the realtime database admin.initializeApp(functions.config().firebase); // initialize the Firebase Admin SDK
Создайте функцию init_push
. Обратите внимание, что триггер HTTP вызывается для любого метода запроса, поэтому вам нужно отфильтровать метода запроса, который вы хотите обработать. В этом случае мы хотим только обрабатывать запросы POST
. Мы ожидаем, что приложение отдаст id
, steps
и friend_ids
в качестве данных запроса.
exports.init_push = functions.https.onRequest((request, response) => { if(request.method == 'POST'){ var id = request.body.id; // ID of the user who made the request (Firebase Auth ID) var steps = parseInt(request.body.steps); // latest steps, not recorded yet var friend_ids = request.body.friend_ids.split(','); friend_ids.push(id); // also include the ID of the current user // next: add code for getting the user and friends data } });
Получение данных пользователя и друзей
Затем запросите базу данных Firebase, чтобы проверить, существует ли идентификатор пользователя. Это служит средством для защиты ендпоинта, поэтому не каждый может инициировать push-уведомления. (Разумеется, реальное приложение должно обладать гораздо более надежной защитой, чтобы пользователи не могли подделывать свои собственные данные или данные кого-либо еще.)
Если пользователь существует, запросите базу данных еще раз, чтобы она вернула всех пользователей. Обратите внимание, что Firebase в настоящее время не предоставляет способ возврата записей на основе массива идентификаторов, поэтому нам придется сами фильтровать соответствующие данные:
admin.database().ref('/users') .orderByChild('id') .limitToFirst(1) .equalTo(id) .once('value').then(snapshot => { var user_data = snapshot.val(); if(user_data){ // get all users from the database admin.database().ref('/users') .once('value').then(snapshot => { // next: add code for getting the current user's data and their friends data }); } });
Затем перебираем результаты, возвращаемые из Firebase, и создаем новый массив, в котором размещаются данные friends_data
. Как только это будет сделано, отсортируйте массив в соответствии с количеством шагов каждого пользователя. Первый с самым высоким числом шагов имеет первый индекс.
var friends_data = []; var current_user_data = null; var notification_data = {}; var has_notification = false; var users = snapshot.val(); for(var key in users){ var user_id = users[key].id; if(friend_ids.indexOf(user_id) != -1 && id != user_id){ // the current user's friends friends_data.push(users[key]); }else if(id == user_id){ // the current user current_user_data = users[key]; } } // sort in descending order by the number of steps var sorted_friends_data = friends_data.sort(function(a, b) { return b.steps - a.steps; }); // next: add code for constructing the notification payload
Создаем пейлоад нотификации
Теперь мы готовы определить, кто получит уведомление и сконструируем пейлоад для уведомлений. Кто на первом месте? Это текущий пользователь или один из друзей пользователя? Поскольку текущий пользователь также может побить свой собственный рекорд, то нам просто нужно проверить, была ли эта запись побита.
if(steps > sorted_friends_data[0].steps){ // notify friend who was overtaken var diff_steps = steps - sorted_friends_data[0].steps; notification_data = { payload: { title: 'One of your friends beat your record', body: 'Too bad, your friend ' + current_user_data.user_name + ' just overtook you by ' + diff_steps + ' steps' }, device_token: sorted_friends_data[0].device_token }; has_notification = true; }else if(steps > current_user_data.steps){ // notify current user var diff_steps = steps - current_user_data.steps; notification_data = { payload: { title: 'You beat your record!', body: 'Congrats! You beat your current record by ' + diff_steps + ' steps!' }, device_token: current_user_data.device_token }; has_notification = true; } // next: add code for sending push notification
Отправка уведомления
Наконец, отправьте уведомление:
if(has_notification){ var payload = { notification: notification_data.payload }; // send push notification admin.messaging().sendToDevice(notification_data.device_token, payload).then(function(res) { response.send(JSON.stringify({'has_notification': true})); // inform the app that a notification was sent }) .catch(function(error) { response.send(JSON.stringify(error)); // send the push notification error to the app }); }else{ response.send(JSON.stringify({'has_notification': false})); // inform the app that a notification was not sent }
Обновление кода приложения
Раньше вы настраивали приложение, чтобы оно могло получать push-уведомления. На этот раз вы добавите код, чтобы ваше приложение могло обрабатывать эти push-уведомления и отображать их пользователю.
Получение Push-уведомлений
Первое, что вам нужно сделать для получения push-уведомлений, - это обновить функцию firebase.init()
, чтобы включить прослушиватель для приема токена устройства:
onPushTokenReceivedCallback: function(token) { // temporarily save it to application settings until such time that // the user logs in for the first time applicationSettings.setString('device_token', token); },
Эта функция выполняется только один раз, поэтому вам необходимо локально сохранить токен, используя настройки приложения. Позже это позволит нам получить токен устройства, когда пользователь входит в систему в первый раз. Если вы все еще помните из предыдущего урока, мы сохраняем данные пользователя в Firebase при первом входе в систему.
Затем вы можете добавить слушателя для получения уведомлений. Это отобразит окно предупреждения, в котором будет использоваться заголовок и тело сообщения:
onMessageReceivedCallback: function(message) { dialogs.alert({ title: message.title, message: message.body, okButtonText: "ok" }); },
Сохранение токена устройства в Firebase
FireBase Cloud Messaging требует токена устройства при отправке push-уведомления на конкретное устройство. Поскольку мы уже используем Firebase, мы просто сохраним токен устройства вместе с пользовательскими данными. Для этого вам нужно отредактировать код для сохранения данных пользователя, чтобы включить токен устройства, который мы получили раньше:
if(firebase_result.value == null){ var device_token = applicationSettings.getString('device_token'); var user_data = { 'uid': fb_result.uid, 'user_name': fb_result.name, 'profile_photo': fb_result.profileImageURL, 'device_token': device_token }; }
Тригерим пуш уведомления
Пуш уведомление срабатывает, когда происходит одна из двух вещей:
- когда пользователь бьет свой собственный рекорд
- когда один из друзей пользователя бьет свой рекорд и выходит на первое место
Первое достаточно простое, поэтому нет необходимости в дополнительной настройке. Но для второго потребуется немного поработать. Во-первых, вы должны отредактировать код, когда изменяется состояние auth. Сразу после извлечения идентификаторов друзей из результата Facebook вам нужно сохранить идентификаторы друзей, используя настройки приложения.
// extracting the friend IDs from the Facebook result var friends_ids = r.data.map(function(obj){ return obj.id; }); // save the friend IDs applicationSettings.setString('friends_ids', JSON.stringify(friends_ids)); friends_ids.push(user[user_key].id);
Затем обновите код, когда пользователь перестает отслеживать свою прогулку. Сразу после кода для создания пользовательских данных для обновления пользователя, получите идентификаторы друзей из параметров приложения и включите их в объект, который содержит данные запроса для запуска push-уведомления.
// construct the user data for updating the user's distance and steps var user_key = applicationSettings.getString('user_key'); var user = applicationSettings.getString('user'); var user_data = JSON.parse(user); user_data[user_key].distance = total_distance; user_data[user_key].steps = total_steps; // get friend IDs var friends_ids = JSON.parse(applicationSettings.getString('friends_ids')); var request_data = { 'id': user_data[user_key].id, 'friend_ids': friends_ids.join(','), 'steps': total_steps };
Сделайте запрос к ендпоинту облачных функций Firebase, которую вы создали ранее. После того как будет получен ответ об успешном завершении, только тогда данные пользователя будут обновлены в базе данных Firebase.
http.request({ url: "https://us-central1-pushapp-ab621.cloudfunctions.net/init_push", method: "POST", headers: { "Content-Type": "application/json" }, content: JSON.stringify(request_data) }).then(function (response) { var statusCode = response.statusCode; if(statusCode == 200){ // update the user's data on Firebase firebase.update( '/users', user_data ); } }, function (e) { console.log('Error occurred while initiating push: ', e); });
Тестирование Push-уведомлений
Вы можете протестировать отправку push-уведомлений, сначала удалив приложение из эмулятора или устройства. Это позволяет нам правильно запускать функцию для получения токена устройства. Не забудьте добавить console.log
для вывода токена устройства:
onPushTokenReceivedCallback: function(token) { applicationSettings.setString('device_token', token); console.log('device token: ', device_token); // <-- add this }
Когда токен устройства выводится в консоли NativeScript, скопируйте его, щелкните меню «База данных» на панели управления приложениями Firebase и добавьте его в качестве токена устройства всем пользователям приложения. Используйте device_token
как имя свойства.
Чтобы вызвать push-уведомление, вы можете использовать curl для отправки запроса POST
к функции Firebase:
curl -X POST -H "Content-Type:application/json" YOUR_FIREBASE_FUNCTION_ENDPOINT -d '{"id":"ID OF A FIREBASE USER", "steps":NUMBER_OF_STEPS, "friend_ids":"COMMA,SEPARATED,FIREBASE,USER_IDs"}'
Если curl у вас не установлен, вы можете использовать приложение Postman для отправки запросов. Используйте следующие настройки для запроса:
- Метод запроса:
POST
- URL: ендпоинт вашей функции Firebase
- Ключ заголовка:
Content-type
- Значение заголовка:
application/json
- Тело:
{"id":"ID OF A FIREBASE USER", "steps":NUMBER_OF_STEPS, "friend_ids":"COMMA,SEPARATED,FIREBASE,USER_IDs"}
После запуска вы увидите вывод, похожий на следующий:

Если приложение не открыто, вы увидите уведомление в области уведомлений:

Заключение
Поздравляю! Наконец, вы закончили фитнес-приложение. В течение четырех учебников вы создавали приложение NativeScript, в котором используются карты Google, база данных SQLite, Firebase Realtime и Firebase Cloud Messaging. Теперь у вас неплохая основа для создания приложений NativeScript, которые используют эти технологии.
Чтобы узнать больше о NativeScript или других кросс-платформенных мобильных технологиях, обязательно ознакомьтесь с некоторыми нашими другими курсами и учебниками здесь, на Envato Tuts +!
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post