【发布时间】:2018-05-26 00:41:03
【问题描述】:
我尝试在 node.js 中创建一个通知服务器,它从数据库中获取通知,编辑其有效负载,通过 Firebase 云消息传递发送它们,然后在数据库中编辑它们的状态。
Javascript 不是我的主要语言,所以我希望他们在这段代码中没有太多的误解。
为此,我使用了一些 Promises 和一个 Promise.all。
目前,问题是当我调用 firebase.admin.messaging().sendToDevice 时,我的应用程序永远不会结束执行。
代码如下:
main.js:
'use strict';
global.basePath = __dirname + '/';
const conf = require('./config/config'),
db = require('./lib/database'),
builder = require('./notify/builder');
const gender = conf.genderId[process.argv[2]],
type = conf.typeId[process.argv[3]],
confSql = conf.inc.prod ? conf.mysql.prod : conf.mysql.dev,
database = new db.database(confSql);
const notify = new Promise(
(resolve, reject) => {
if (typeof(gender) !== 'number' && typeof(type) !== 'number') {
return reject('Error: gender and type are mandatory');
}
resolve();
}
);
function main () {
notify
//Get the notifications from DB - They are already group by user
.then( () => { return database.getNotifications(gender, type); })
//Set the payload, send to Firebase, and update the status in DB
// <-- Inside it is the call to Firebase
.then( rows => { return Promise.all(rows.map(builder.handleNotification)); }
, err => {
return database.close().then( () => {
return Promise.reject(err)
} );
}
)
.then(() => {
console.log('Success ! The DB and the app must close.');
database.close();
})
.catch(console.log.bind(console))
;
}
main();
builder.js:
'use strict';
const conf = require('./../config/config'),
sender = require('./sender'),
database = require('./../lib/database');
//This is called inside an array.map
//It is a chain of Promises that are resolved or rejected in a Promise.all
function handleNotification( notification){
let notif = notification;
return Promise.resolve(setGroupPayload(notification))
.then(sender.send)
.then(console.log)
.catch(error => {
return Promise.reject(error);
});
}
function setGroupPayload (notification){
//Do some change on notifications
// (...)
return notification;
}
module.exports = {
handleNotification: handleNotification
};
数据库.js:
const mysql = require( 'mysql' );
function Database(config) {
this.connection = mysql.createConnection( config );
}
Database.prototype.query = function query( sql, args ) {
return new Promise( ( resolve, reject ) => {
this.connection.query( sql, args, ( err, rows ) => {
if ( err )
return reject( err );
resolve( rows );
} );
} );
};
Database.prototype.ping = function ping(){
return new Promise( ( resolve, reject) => {
this.connection.ping( err => {
if ( err )
return reject( err );
resolve('Server responded to ping');
} );
} );
};
Database.prototype.close = function close() {
console.log('close connection');
return new Promise( ( resolve, reject ) => {
this.connection.end( err => {
if ( err )
return reject( err );
console.log('connection closed');
resolve();
} );
} );
};
Database.prototype.getNotifications = function getNotifications (gender, type) {
const query = `(...)`;
const params = [gender, type];
return this.query(query, params);
};
module.exports = {
database: Database
};
最后是 sender.js :
'use strict';
const firebase = require('./../lib/firebase-admin');
/**
*
* @param notification
* @returns {Promise}
*/
function send (notification) {
if (notification.message === false) {
return Promise.reject(["payload is empty"]);
}
if (!(notification.token && notification.token.length > 0)) {
return Promise.reject(["target is empty."]);
}
const options = {
contentAvailable: true
};
//When this is called here, the app never ends
return firebase.admin.messaging().sendToDevice(notification.token, notification.message, options); /
}
module.exports = {
send: send
};
我收到了来自firebase.admin.messaging().sendToDevice(notification.token, notification.message, options) 的以下回复,即Promise.resolve:
[ { error: { [Error: The provided registration token is not registered. A previously valid registration token can be unregistered for a variety of reasons. See the error documentation for more details. Remove this registration token and stop using it to send messages.] errorInfo: [Object], codePrefix: 'messaging' } } ]
这是正确的,因为令牌无效。我想处理这个响应。但我不明白,为什么我的应用程序永远不会结束?看起来他们是 Promise.all 中一个永无止境的承诺,阻止应用程序结束。
我也尝试处理来自 Firebase 的响应并将 Promise.reject 发送到承诺链,但没有成功...
那么...我哪里错了? 非常感谢任何可以帮助我解决此错误的人。
编辑:
按照@JimWright 的要求,我在builder.js 的catch 之前添加了.then()。
结果如下:
结果如下:
{ results: [ { error: [Object] } ],
canonicalRegistrationTokenCount: 0,
failureCount: 1,
successCount: 0,
multicastId: 6057186106180078000 }
Success ! The DB and the app must close.
close connection
connection closed
【问题讨论】:
-
尝试在
builder.js的捕获之前添加then()- 你在那里得到结果吗?还要记录错误以查看是否有任何内容。 -
是来自
then()还是catch()? -
感谢您的回答@JimWright。我已经编辑了帖子。 sendToDevice 发送一个 Promise.resolve()。所以即使它发送一个错误,它仍然是一个解析。
标签: javascript node.js firebase promise firebase-cloud-messaging