【问题标题】:heroku server and firebaseheroku 服务器和火力基地
【发布时间】:2016-10-20 08:24:16
【问题描述】:

我正在尝试创建一个服务器来监听 firebase 数据库中所做的更改,然后将电子邮件发送到某个电子邮件地址。我设法实现了firebase和sendgrid,我已经通过向数据库添加一些条目并发送测试邮件进行了测试。所以 sendgrid 和 firebase 正在工作。这里的问题取决于我如何设法发送电子邮件,每次打开应用程序时它都会发送电子邮件。

所以问题来了,如果每次应用程序打开它都会执行 js 文件中的代码。当我添加代码以侦听数据库中添加的子事件时,每次打开应用程序时都会调用它,因此多个侦听器将处于活动状态,并且我假设将针对单个事件发送多封电子邮件。

所以我一无所知,无论如何这只会被调用一次吗?或者我不应该多次打开“应用程序”?还是我没有以正确的方式部署服务器?

我的目标是,一旦我部署服务器,它将自动执行其编写的操作,而无需在 heroku 中实际打开“应用程序”,或者至少在应用程序打开时不会再次调用代码,部署时只需一次。

这是 server.js 的代码

var firebase = require('firebase');
var helper = require('sendgrid').mail;

firebase.initializeApp({
  serviceAccount: "./DB-A2312SDA.json",
  databaseURL: "https://DATABASENAME.firebaseio.com/"
});

// Email

var from_email = new helper.Email('example@example.com');
var to_email = new helper.Email('example@gmail.com');
var subject = 'Hello World from the SendGrid Node.js Library!';
var content = new helper.Content('text/plain', 'Hello, Email!');
var mail = new helper.Mail(from_email, subject, to_email, content);

var sg = require('sendgrid')(process.env.SG_API_KEY);
var request = sg.emptyRequest({
  method: 'POST',
  path: '/v3/mail/send',
  body: mail.toJSON(),
});

sg.API(request, function(error, response) {
  console.log(response.statusCode);
  console.log(response.body);
  console.log(response.headers);
});

这是 package.json

{
  "name": "server_test",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "engines": {
    "node": "6.9.0"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "firebase": "^3.5.1",
    "sendgrid": "^4.7.0"
  }
}

和过程文件

web: node server.js

【问题讨论】:

    标签: node.js heroku firebase firebase-realtime-database sendgrid


    【解决方案1】:

    通常在这种情况下,您的数据库中有一个节点,该节点指示您需要向其发送消息的地址。例如,如果您想向已注册某项内容的人发送欢迎信息,您可以将其建模为:

    welcomeMessageQueue
        $pushid
            email: "rialcom@company.com"
            firstName: "Ralcom"
    

    你不能在你的节点脚本中附加一个监听器:

    1. 对于此队列中的每条消息
    2. 向该电子邮件地址发送消息
    3. 然后从队列中删除该项目

    这里重要的是,一旦您发送了消息,就从队列中删除该项目。这样,消息只会发送一次。

    一个简单的方法是:

    var ref = firebase.database().ref();
    var queue = ref.child('welcomeMessageQueue');
    queue.on('child_added', function(snapshot) {
        var message = snapshot.val();
        var sg = require('sendgrid')(process.env.SG_API_KEY);
        var request = sg.emptyRequest({
          method: 'POST',
          path: '/v3/mail/send',
          body: mail.toJSON(),
        });
    
        sg.API(request)
          .then(function(response) {
              snapshot.ref.remove();
          });
    })
    

    如需更可扩展的方法,请查看firebase-queue

    有关使用此方法的简单教程,请参阅blog post on sending push notifications

    【讨论】:

    • 所以,我无法控制实际服务器代码将被调用多少次,而是控制数据库数据本身? - 换句话说,激活多个监听器并不重要?
    • Frank 我试过你的代码,但它没有按我预期的那样工作。该应用程序仅在经过特定时间或在 Heroku 中打开该应用程序时才发送邮件。它似乎并不关心是否将数据添加到数据库中,看起来服务器只有在有人访问 heroku 应用程序时才处于活动状态。
    • 确实可以。我没有在 Heroku 上运行此类后端的经验,它可能会管理代码的生命周期。在管理较少的环境(例如 Digital Ocean、Google Compute Engine 或 App Engine 灵活环境中的 node.js)上,此类进程运行良好。
    • 谢谢弗兰克,我将尝试使用数字海洋或谷歌计算引擎,或者我认为最容易管理的引擎。也许 heroku 像这样管理生命周期,因为我使用的是免费帐户,我不确定,但可能是这样。任何您认为最有效的建议,我将不胜感激。
    猜你喜欢
    • 2016-09-17
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多