3

I use Lambda to Firebase message. I ref this. But the lambda function still timeout because it cannot connect to google server.

Handler.js

/ [START imports]
const firebase = require('firebase-admin');
const serviceAccount = require("../serviceAccount.json");

module.exports.message = (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false;  
  const registrationToken = "xxxxxxx";

  const payload = {
    data: {
      score: "850",
      time: "2:45"
    }
  };

  // [START initialize]
  if(firebase.apps.length == 0) {   // <---Important!!! In lambda, it will cause double initialization.
    firebase.initializeApp({
      credential: firebase.credential.cert(serviceAccount),
      databaseURL: 'https://messaging-xxxxx.firebaseio.com'
    });
  }

  // Send a message to the device corresponding to the provided
  // registration token.
  firebase.messaging().sendToDevice(registrationToken, payload)
    .then(function(response) {
      // See the MessagingDevicesResponse reference documentation for
      // the contents of response.
      console.log("Successfully sent message:", response);
      callback(null, {
        statusCode: 200,
        body: JSON.stringify("Successful!"),
      });
    })
    .catch(function(error) {
      console.log("Error sending message:", error);
      callback(null, {
        statusCode: 500,
        body: JSON.stringify({
          "status": "error",
          "message": error
        })
      })
    });
};

CloudWatch

[Error: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "connect ETIMEDOUT 172.217.26.45:443".]

But I use same serviceAccount.json to run on my ec2 and work find. Does someone encounter this?

4
  • How have you added your serviceAccount.json file? I assume you uploaded a zip to Lambda and it's not just inline code? Commented Feb 18, 2017 at 13:01
  • 1
    Is this thread helpful? stackoverflow.com/questions/36508974/… Commented Feb 18, 2017 at 14:44
  • @Deif I use serverless to upload my serviceAccount.json file. Commented Feb 19, 2017 at 15:56
  • @jacobawenger Thank you the link. You give me right direction! Commented Feb 19, 2017 at 15:57

1 Answer 1

5

After a couple hours struggling, I finally find the reason. Because my Lambda using VPC to connect RDS and the network interface of VPC only have private IP.

AWS document:

When you add VPC configuration to a Lambda function, it can only access resources in that VPC. If a Lambda function needs to access both VPC resources and the public Internet, the VPC needs to have a Network Address Translation (NAT) instance inside the VPC.

So I need to create NAT inside the VPC. I follow this Blog and problem solved.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.