使用 NativeScript 开发实时应用程序:实现推送通知

wufei123 2024-06-02 阅读:52 评论:0
nativescript 是一个使用 xml、css 和 javascript 构建跨平台本机移动应用程序的框架。在本系列中,我们将尝试使用 nativescript 应用程序可以完成的一些很酷的事情:地理位置和 google 地图集成、s...

nativescript 是一个使用 xml、css 和 javascript 构建跨平台本机移动应用程序的框架。在本系列中,我们将尝试使用 nativescript 应用程序可以完成的一些很酷的事情:地理位置和 google 地图集成、sqlite 数据库、firebase 集成和推送通知。在此过程中,我们正在构建一个具有实时功能的健身应用程序,该应用程序将使用这些功能。

在本教程中,您将了解使用 Firebase 云消息服务向 NativeScript 应用添加推送通知是多么轻松。

您将要创建的内容

继续上一教程,您将向应用添加推送通知。当用户打破当前记录或其中一个朋友取代他们获得第一名时,将会触发通知。

设置项目

如果您已遵循之前的 Firebase 教程,则只需使用同一项目并构建我们将在本教程中添加的功能即可。否则,您可以创建一个新项目并将起始文件复制到项目的应用程序文件夹中。

tns create fitApp --appid "com.yourname.fitApp"

之后,您还需要安装地理位置、Google 地图、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 地图插件。您可以阅读之前教程中的安装 Google 地图插件部分,了解有关如何执行此操作的完整说明。

接下来,安装用于格式化日期的 fecha 库:

npm install --save fecha

之后,您还需要配置 Firebase 插件。请务必阅读上一教程中的以下部分,以便您可以运行应用程序:

  • 运行项目
  • 设置 Firebase 应用
  • 设置 Facebook 应用
  • 安装 Firebase 插件
  • 配置 Facebook 集成

由于我们已经在上一篇文章中设置了 Firebase 插件,因此只需完成少量工作即可设置推送通知。

首先,您必须进入 node_modules/nativescript-plugin-firebase 目录并运行 npm run config 来重新配置插件。这次,选择 Facebook 身份验证和消息传递。

完成后,打开项目根目录中的 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并在 中添加以下服务。这将为应用启用 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 云函数

您将使用 Firebase Cloud Functions 创建一个用于发送推送通知的服务器。此 Firebase 功能用于在您正在使用的 Firebase 功能中发生特定事件时运行后端代码 - 例如,如果实时数据库中保存了新数据,或者通过Firebase 身份验证服务。对于此应用,您将使用 HTTP 触发器在移动应用向特定端点发出请求时发送推送通知。

要使用 Firebase Cloud Functions,您首先需要全局安装 firebase-tools 软件包:

npm install -g firebase-tools

接下来,创建一个新文件夹来存放服务器代码。这应该位于您的应用程序文件夹之外。在该文件夹中,安装 firebase-functions 软件包:

npm install firebase-functions@latest --save

安装完成后,通过运行 firebase login 登录 Firebase。这将打开一个新的浏览器选项卡,允许您使用 Google 帐户登录。完成整个过程并同意所请求的所有权限。

登录后,您现在可以初始化特定 Firebase 项目的 Firebase 函数:

firebase init functions

这将询问您是否要设置默认项目。选择您在上一教程中创建的 Firebase 项目:

使用 NativeScript 开发实时应用程序:实现推送通知

接下来,系统会询问您是否要安装依赖项。说是。

安装完所有依赖项后,您应该会在目录中看到一个 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:

使用 NativeScript 开发实时应用程序:实现推送通知

从浏览器访问该网址即可查看输出“Hello from Firebase!”

添加服务器代码

现在您已准备好添加用于实现推送通知的代码。首先,您将添加服务器组件的代码,然后添加应用程序的代码。

打开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 数据库以检查用户 ID 是否存在。这是保护端点的一种方式,因此并非任何人都可以触发推送通知。 (当然,真正的应用程序应该具有更好的后端安全性,以便用户无法欺骗自己的数据或其他人的数据。)

如果用户确实存在,则再次查询数据库,以便返回所有用户。请注意,Firebase 目前不提供基于 ID 数组返回记录的方法,因此我们必须自己过滤相关数据:

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 } 更新应用代码

之前,您设置了应用程序,以便它能够接收推送通知。这次,您将添加代码,以便您的应用程序可以处理这些推送通知并将其显示给用户。

接收推送通知

为了接收推送通知,您需要做的第一件事是更新 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 在向特定设备发送推送通知时需要设备令牌。由于我们已经在使用 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 }; } 触发推送通知

当发生以下两种情况之一时,将触发推送通知:

  • 当用户打破当前记录时
  • 当用户的一个朋友打破记录并获得第一名时

第一个很简单,因此实际上不需要额外的设置。但对于第二个,你需要做一些工作。首先,您必须编辑身份验证状态更改时的代码。从 Facebook 结果中提取好友 ID 后,您必须使用应用程序设置保存好友 ID。

// 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);

接下来,更新用户何时停止跟踪其步行的代码。在构建更新用户的用户数据的代码之后,从应用程序设置中获取好友 ID,并将其包含在包含触发推送通知的请求数据的对象中。

// 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 Cloud Functions 端点发出请求。一旦返回成功响应,用户的数据才会在 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); }); 测试推送通知

您可以通过首先从模拟器或设备中卸载应用程序来测试推送通知的发送。这使得我们能够正确触发获取设备令牌的函数。请务必添加 console.log 以输出设备令牌:

onPushTokenReceivedCallback: function(token) { applicationSettings.setString('device_token', token); console.log('device token: ', device_token); // <-- add this }

当设备令牌在 NativeScript 控制台中输出时,将其复制,点击 Firebase 应用信息中心上的数据库菜单,并将其作为设备令牌添加给应用的所有用户。使用 device_token 作为属性名称。

要触发推送通知,您可以使用 curl 向 Firebase 函数端点发出 POST 请求:

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
  • 网址:您的 Firebase 函数端点
  • 标头键: 内容类型
  • 标头值: application/json
  • 正文: 
{"id":"ID OF A FIREBASE USER", "steps":NUMBER_OF_STEPS, "friend_ids":"COMMA,SEPARATED,FIREBASE,USER_IDs"}

触发后,您将看到类似于以下内容的输出:

使用 NativeScript 开发实时应用程序:实现推送通知

如果应用当前未打开,您将在通知区域中看到通知:

使用 NativeScript 开发实时应用程序:实现推送通知

结论

恭喜!您终于完成了健身应用程序。在四个教程的过程中,您已经构建了一个使用 Google 地图、SQLite、Firebase 实时数据库和 Firebase 云消息传递的 NativeScript 应用。现在您已经为构建使用这些技术的 NativeScript 应用程序奠定了良好的基础。

要了解有关 NativeScript 或其他跨平台移动技术的更多信息,请务必查看我们在 Envato Tuts+ 上的其他一些课程和教程!

以上就是使用 NativeScript 开发实时应用程序:实现推送通知的详细内容,更多请关注知识资源分享宝库其它相关文章!

版权声明

本站内容来源于互联网搬运,
仅限用于小范围内传播学习,请在下载后24小时内删除,
如果有侵权内容、不妥之处,请第一时间联系我们删除。敬请谅解!
E-mail:dpw1001@163.com

分享:

扫一扫在手机阅读、分享本文

发表评论
热门文章
  • BioWare埃德蒙顿工作室面临关闭危机,龙腾世纪制作总监辞职引关注(龙腾.总监.辞职.危机.面临.....)

    BioWare埃德蒙顿工作室面临关闭危机,龙腾世纪制作总监辞职引关注(龙腾.总监.辞职.危机.面临.....)
    知名变性人制作总监corrine busche离职bioware,引发业界震荡!外媒“smash jt”独家报道称,《龙腾世纪:影幢守护者》制作总监corrine busche已离开bioware,此举不仅引发了关于个人职业发展方向的讨论,更因其可能预示着bioware埃德蒙顿工作室即将关闭而备受关注。本文将深入分析busche离职的原因及其对bioware及游戏行业的影响。 Busche的告别信:挑战与感激并存 据“Smash JT”获得的内部邮件显示,Busche离职原...
  • 闪耀暖暖靡城永恒怎么样-闪耀暖暖靡城永恒套装介绍(闪耀.暖暖.套装.介绍.....)

    闪耀暖暖靡城永恒怎么样-闪耀暖暖靡城永恒套装介绍(闪耀.暖暖.套装.介绍.....)
    闪耀暖暖钻石竞技场第十七赛季“华梦泡影”即将开启!全新闪耀性感套装【靡城永恒】震撼来袭!想知道如何获得这套精美套装吗?快来看看吧! 【靡城永恒】套装设计理念抢先看: 设计灵感源于夜色中的孤星,象征着淡然、漠视一切的灰色瞳眸。设计师希望通过这套服装,展现出在虚幻与真实交织的夜幕下,一种独特的魅力。 服装细节考究,从面料的光泽、鞋跟声响到裙摆的弧度,都力求完美还原设计初衷。 【靡城永恒】套装设计亮点: 闪耀的绸缎与金丝交织,轻盈的羽毛增添华贵感。 这套服装仿佛是从无尽的黑...
  • python怎么调用其他文件函数

    python怎么调用其他文件函数
    在 python 中调用其他文件中的函数,有两种方式:1. 使用 import 语句导入模块,然后调用 [模块名].[函数名]();2. 使用 from ... import 语句从模块导入特定函数,然后调用 [函数名]()。 如何在 Python 中调用其他文件中的函数 在 Python 中,您可以通过以下两种方式调用其他文件中的函数: 1. 使用 import 语句 优点:简单且易于使用。 缺点:会将整个模块导入到当前作用域中,可能会导致命名空间混乱。 步骤:...
  • 俄罗斯引擎yandex入口官网地址 yandex网址在线免费进入(俄罗斯.官网.在线免费.入口.地址......)

    俄罗斯引擎yandex入口官网地址 yandex网址在线免费进入(俄罗斯.官网.在线免费.入口.地址......)
    俄罗斯引擎yandex官网地址入口在哪里?这是不少网友都关注的问题,接下来由php小编为大家带来yandex网址在线免费进入,感兴趣的网友一起随小编来瞧瞧吧! 俄罗斯引擎yandex入口官网地址 1、俄罗斯引擎yandex入口官网地址☜☜☜☜☜点击进入 2、yandex网址在线免费进入☜☜☜☜☜点击进入 【俄罗斯引擎yandex】 1、Yandex的搜索引擎在俄罗斯拥有极高的市场份额,其算法针对俄语和斯拉夫语系进行了优化,能更好地理解用户意图,提供更精准的搜索结果。它不仅...
  • 斗魔骑士哪个角色强势-斗魔骑士角色推荐与实力解析(骑士.角色.强势.解析.实力.....)

    斗魔骑士哪个角色强势-斗魔骑士角色推荐与实力解析(骑士.角色.强势.解析.实力.....)
    斗魔骑士角色选择及战斗策略指南 斗魔骑士游戏中,众多角色各具特色,选择适合自己的角色才能在战斗中占据优势。本文将为您详细解读如何选择强力角色,并提供团队协作及角色培养策略。 如何选择强力角色? 斗魔骑士的角色大致分为近战和远程两种类型。近战角色通常拥有高攻击力和防御力,适合冲锋陷阵;远程角色则擅长后方输出,并依靠灵活走位躲避攻击。 选择角色时,需根据个人游戏风格和喜好决定。喜欢正面硬刚的玩家可以选择战士型角色,其高生命值和防御力能承受更多伤害;偏好策略性玩法的玩家则可以选择法...