NativeScript は、XML、CSS、JavaScript を使用してクロスプラットフォームのネイティブ モバイル アプリケーションを構築するためのフレームワークです。このシリーズでは、位置情報と Google マップの統合、SQLite データベース、Firebase の統合、プッシュ通知など、NativeScript アプリで実行できるいくつかの優れた機能を試していきます。その過程で、アプリで使用されるリアルタイム機能を備えたフィットネス アプリを構築しています。
このチュートリアルでは、Firebase Cloud Messaging Service を使用して NativeScript アプリにプッシュ通知を追加するのがいかに簡単かを学びます。
前のチュートリアルから引き続き、アプリにプッシュ通知を追加します。ユーザーが現在の記録を破ったとき、またはユーザーの代わりに友人の 1 人が 1 位になったときに、通知がトリガーされます。
以前の Firebase チュートリアルに従った場合は、同じプロジェクトを使用して、このチュートリアルで追加する機能を構築するだけです。それ以外の場合は、新しいプロジェクトを作成し、開始ファイルをプロジェクトのアプリケーション フォルダーにコピーします。
リーリーその後、Geolocation、Google Maps、SQLite、Firebase プラグインもインストールする必要があります:
リーリーインストール後、Google マップ プラグインを設定する必要があります。これを行う方法の詳細については、前のチュートリアルの Google マップ プラグインのインストール セクションをご覧ください。
次に、日付をフォーマットするための fecha ライブラリをインストールします。
リーリーその後、Firebase プラグインも設定する必要があります。アプリケーションを実行できるように、前のチュートリアルの次のセクションを必ず読んでください:
前回の記事ですでに Firebase プラグインをセットアップしたため、プッシュ通知をセットアップするために行う作業はほんの少しだけです。
まず、node_modules/nativescript-plugin-firebase ディレクトリに移動し、npm run config
を実行して、プラグインを再構成する必要があります。今回は、「Facebook 認証とメッセージング」を選択します。
終了したら、プロジェクトのルート ディレクトリにある firebase.nativescript.json ファイルを開き、messaging
が true
:
次に、app/App_Resources/Android/AndroidManifest.xml を開き、<application></application>
に次のサービスを追加します。これにより、アプリの Firebase Messaging が有効になります:
tns run android
を実行すると、プロジェクトを実行できます。ただし、このアプリは地理位置情報機能に基づいて構築されているため、位置をすばやく設定および変更するには、GPS エミュレーターを使用することをお勧めします。これを行う方法は、前のチュートリアルの アプリの実行 セクションで学習できます。
ビルド エラーが発生した場合は、プラットフォームを削除してアプリケーションを再実行できます。
リーリーFirebase Cloud Functions を使用して、プッシュ通知を送信するためのサーバーを作成します。この Firebase 機能は、使用している Firebase 機能内で特定のイベントが発生したときに、たとえば新しいデータがライブ データベースに保存された場合や Firebase Authentication サービスを通じてバックエンド コードを実行するために使用されます。このアプリでは、モバイル アプリが特定のエンドポイントにリクエストを行ったときに HTTP トリガーを使用してプッシュ通知を送信します。
Firebase Cloud Functions を使用するには、まず firebase-tools
パッケージをグローバルにインストールする必要があります:
次に、サーバー コードを保存する新しいフォルダーを作成します。これはアプリケーション フォルダーの外にある必要があります。そのフォルダーに、firebase-functions
パッケージをインストールします:
インストールが完了したら、firebase login
を実行して Firebase にログインします。これにより、新しいブラウザ タブが開き、Google アカウントでログインできるようになります。プロセス全体を完了し、要求されたすべての権限に同意します。
ログイン後、特定の Firebase プロジェクトの Firebase 関数を初期化できるようになります:
リーリーデフォルトのプロジェクトを設定するかどうかを尋ねられます。前のチュートリアルで作成した Firebase プロジェクトを選択します:
次に、依存関係をインストールするかどうかを尋ねられます。と言われています。
すべての依存関係がインストールされると、ディレクトリ内に firebase.json ファイルと functions フォルダーが表示されます。処理しようとしているファイルは、functions/index.js ファイルです。ファイルを開くと、次の内容が表示されます:
リーリーhelloWorld
関数のコメントを解除すると、HTTP トリガーが実行されていることがわかります。
次のコマンドを実行して関数をクラウドにデプロイします:
リーリーデプロイが完了すると、関数がデプロイされた URL が表示されます:
从浏览器访问该网址即可查看输出“Hello from Firebase!”
现在您已准备好添加用于实现推送通知的代码。首先,您将添加服务器组件的代码,然后添加应用程序的代码。
打开functions/index.js文件并清空其内容。
导入您需要的 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 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
内容类型
application/json
{"id":"ID OF A FIREBASE USER", "steps":NUMBER_OF_STEPS, "friend_ids":"COMMA,SEPARATED,FIREBASE,USER_IDs"}
触发后,您将看到类似于以下内容的输出:
如果应用当前未打开,您将在通知区域中看到通知:
恭喜!您终于完成了健身应用程序。在四个教程的过程中,您已经构建了一个使用 Google 地图、SQLite、Firebase 实时数据库和 Firebase 云消息传递的 NativeScript 应用。现在您已经为构建使用这些技术的 NativeScript 应用程序奠定了良好的基础。
要了解有关 NativeScript 或其他跨平台移动技术的更多信息,请务必查看我们在 Envato Tuts+ 上的其他一些课程和教程!
以上がNativeScript を使用したリアルタイム アプリケーションの開発: プッシュ通知の実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。