Monaca,ncmb,pusherを用いてmBaaSとPusherを使ってチャットアプリを作るを読み進めながらチャットアプリを作っています。
サンプルコード通りにやってみたのですが、チャットの内容が画面に反映されません。
メッセージを入力して、送信ボタンを押した後、一度ログイン画面に戻ってから再度ログインしなおすと、先程入力したメッセージが表示されます。
index.html
html
1<!DOCTYPE HTML> 2<html> 3<head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"> 6 <meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'"> 7 <script src="components/loader.js"></script> 8 <script src="lib/onsenui/js/onsenui.min.js"></script> 9 10 <link rel="stylesheet" href="components/loader.css"> 11 <link rel="stylesheet" href="lib/onsenui/css/onsenui.css"> 12 <link rel="stylesheet" href="lib/onsenui/css/onsen-css-components.css"> 13 <link rel="stylesheet" href="css/style.css"> 14 <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> 15 <script src="https://js.pusher.com/5.1/pusher.min.js"></script> 16 <script src="js/app.js"></script> 17</head> 18<body> 19 <ons-navigator swipeable id="nav" page="login.html"></ons-navigator> 20 <template id="login.html"> 21 <ons-page id="login"> 22 <div class="join-area" style="text-align: center; margin-top: 30px;"> 23 <h4>チャットルームにログインしてください</h4> 24 <p> 25 <ons-input id="userName" modifier="underbar" placeholder="ユーザ名" float></ons-input><br /> 26 <ons-input id="chatId" modifier="underbar" placeholder="chatId" float></ons-input> 27 </p> 28 <p style="margin-top: 30px;"> 29 <ons-button onclick="join()">Join</ons-button> 30 </p> 31 </div> 32 </ons-page> 33 </template> 34</body> 35</html>
chat.html
html
1<ons-page id="chat"> 2 <ons-toolbar> 3 <div class="left"><ons-back-button>Back</ons-back-button></div> 4 <div class="center"></div> 5 </ons-toolbar> 6 <input type="hidden" id="channelId" /> 7 <div class="chat-area"> 8 <ons-list id="chats"></ons-list> 9 </div> 10 <div class="send-area"> 11 <ons-input id="message" placeholder="メッセージ"></ons-input> 12 <ons-button onclick="send()" modifier="quiet">送信</ons-button> 13 </div> 14</ons-page>
app.js
javascript
1 2// This is a JavaScript file 3let pusher; 4let ncmb; 5const app_id = 'MY_PUSHER_APP_ID'; 6const app_cluster = 'MY_PUSHER_CLUSTER'; 7const applicationKey = 'MY_NCMB_APPLICATION_KEY'; 8const clientKey = 'MY_NCMB_CLIENT_KEY'; 9 10// グローバル変数の処理 11ons.ready(function() { 12 pusher = new Pusher(app_id, { 13 cluster: app_cluster, 14 forceTLS: true 15 }); 16 ncmb = new NCMB(applicationKey, clientKey); 17}); 18 19// 初期表示処理 20$(document).on('init', (event) => { 21 if (event.target.id === 'login') { 22 $('#chatId').val('channel'); 23 const userName = localStorage.getItem('userName'); 24 if (userName) 25 $('#userName').val(userName); 26 } 27}); 28 29// チャット画面を表示したときの処理 30$(document).on('show', (event) => { 31 if (event.target.id === 'chat') { 32 const data = event.target.data; 33 $('#channelId').val(data.chatId); 34 connectPusher(data.userName, data.chatId); 35 loadChat(data.userName, data.chatId); 36 } 37}); 38 39// チャット画面から戻った時の処理 40$(document).on('hide', (event) => { 41 if (event.target.id === 'chat') { 42 pusher.unsubscribe($('#channelId').val()); 43 } 44}); 45 46// チャットルームにログインする処理 47const join = () => { 48 const userName = $('#userName').val(); 49 if (userName === '') { 50 ons.notification 51 .alert('ユーザ名を決めてください'); 52 return; 53 } 54 localStorage.setItem('userName', userName); 55 const chatId = $('#chatId').val(); 56 $('#nav')[0].pushPage('chat.html', { 57 data: { userName, chatId } 58 }) 59} 60 61// Pusherに接続する処理 62const connectPusher = (userName, chatId) => { 63 const channel = pusher.subscribe(chatId); 64 channel.bind('message', function(data) { 65 showChat(userName, data); 66 }); 67}; 68 69// 既存のチャットメッセージを読み込む処理 70const loadChat = (userName, channel) => { 71 const Chat = ncmb.DataStore('Chat'); 72 Chat 73 .equalTo('channel', channel) 74 .fetchAll() 75 .then(chats => { 76 for (let chat of chats) { 77 showChat(userName, chat); 78 } 79 }); 80} 81 82// メッセージを一つ表示する処理 83const showChat = (userName, data) => { 84 if (data.userName == userName) { 85 $('#chats').append(` 86 <ons-list-item modifier="nodivider"> 87 <div class="right"> 88 <ons-button style="background-color: green">${data.message}</ons-button> 89 </div> 90 </ons-list-item>`); 91 }else{ 92 $('#chats').append(` 93 <ons-list-item modifier="nodivider"> 94 <ons-button>${data.message}</ons-button> 95 <span class="list-item__subtitle">${data.userName}</span> 96 </ons-list-item>`); 97 } 98} 99 100// メッセージ送信処理 101const send = () => { 102 const message = $('#message').val(); 103 const userName = localStorage.getItem('userName'); 104 const channel = $('#channelId').val(); 105 ncmb.Script 106 .data({ 107 userName, 108 message, 109 channel 110 }) 111 .exec("POST", "push.js") 112 .then(function(res){ 113 $('#message').val(''); 114 }) 115 .catch(function(err){ 116 console.log(err.name + ':' + err.message); 117 }); 118}; 119
push.js(NCMBスクリプト)
ロジック名 push.js
メソッド POST
ファイルの状態 実行可能
バージョン latest
javascript
1const crypto = require("crypto"); 2const request = require('superagent'); 3const NCMB = require('ncmb'); 4module.exports = (req, res) => { 5 const applicationKey = 'MY_NCMB_APPLICATION_KEY'; 6 const clientKey = 'MY_NCMB_CLIENT_KEY'; 7 saveDataStore( 8 applicationKey, 9 clientKey, 10 req.body 11 ).then(() => { 12 return sendPusher( 13 'MY_PUSHER_KEY', 14 'MY_PUSHER_SECRET', 15 'MY_PUSHER_APP_ID', 16 req.body 17 ) 18 }) 19 .then((response) => { 20 res.json({}); 21 }) 22 .catch((err) => res.status(401).json(err)); 23}; 24 25const saveDataStore = (applicationKey, clientKey, body) => { 26 const ncmb = new NCMB(applicationKey, clientKey); 27 const Chat = ncmb.DataStore('Chat'); 28 const chat = new Chat; 29 return chat 30 .set('channel', body.channel) 31 .set('userName', body.userName) 32 .set('message', body.message) 33 .save() 34} 35 36const sendPusher = (authKey, secretKey, appId, body) => { 37 const authTimestamp = Date.now() / 1000; 38 const authVersion = '1.0'; 39 const medhod = 'POST'; 40 const path = `/apps/${appId}/events`; 41 const message = { 42 data: JSON.stringify({ 43 userName: body.userName, 44 message: body.message 45 }), 46 name: "message", 47 channel: body.channel 48 }; 49 const bodyMd5 = crypto 50 .createHash('md5') 51 .update(JSON.stringify(message)) 52 .digest('hex'); 53 const queryString = `auth_key=${authKey}&auth_timestamp=${authTimestamp}&auth_version=${authVersion}&body_md5=${bodyMd5}`; 54 const authSigning = [ 55 medhod, 56 path, 57 queryString 58 ].join("\n"); 59 const signature = crypto 60 .createHmac("SHA256", secretKey) 61 .update(authSigning) 62 .digest("hex"); 63 return request 64 .post(`https://api.pusherapp.com${path}?${queryString}&auth_signature=${signature}`) 65 .set('Content-Type', 'application/json') 66 .send(JSON.stringify(message)) 67}
なお、push.jsの取得結果ログは下記になります。
json
1{ 2 "Status": "DONE", 3 "RequestHeaders": "{\"host\":\"script.mbaas.api.nifcloud.com\",\"connection\":\"close\",\"content-length\":\"68\",\"x-ncmb-timestamp\":\"2020-03-16T07:13:06.154Z\",\"x-ncmb-signature\":\"GmpGgZ5oupwMzVwp9E8gjM7AcDcibIEJeM9vt6dJR+8=\",\"user-agent\":\"Mozilla/5.0 (Linux; Android 7.0; HUAWEI VNS-L22 Build/HUAWEIVNS-L22; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.132 Mobile Safari/537.36\",\"content-type\":\"application/json\",\"accept\":\"text/plain\",\"x-ncmb-sdk-version\":\"javascript-3.0.2\",\"sec-fetch-dest\":\"empty\",\"x-ncmb-application-key\":\"a49971d96d28c90a9310b798083946a4a87a2b50acff4630558fcba804d0e617\",\"origin\":\"file://\",\"x-requested-with\":\"mobi.monaca.debugger\",\"sec-fetch-site\":\"cross-site\",\"sec-fetch-mode\":\"cors\",\"accept-encoding\":\"gzip, deflate\",\"accept-language\":\"ja-JP,ja;q=0.9,en-US;q=0.8,en;q=0.7\"}", 4 "RequestQuery": "{}", 5 "ResponseHeaders": "{\"Content-Type\":\"application/json\"}", 6 "Error": null, 7 "Duration": 1652, 8 "created_at": "2020-03-16T07:13:05.000Z", 9 "updated_at": "2020-03-16T07:13:07.000Z", 10 "ResponseStatus": 401, 11 "ScriptIdentifier": "push.js" 12}
NCMBのデータストアを確認すると、メッセージは入っているので、そこまでは問題無いと思うので、後はPusherからWebSocket通知がアプリに反映されてないだけだと思うのですが、どこか間違えている部分があればご指摘いただけますでしょうか。
ご教授いただけると助かります。
よろしくお願いします。
![guest](/img/icon/icnUserSample.jpg)
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/18 10:30
2020/03/19 00:19