Search code examples
node.jspromiseamazon-dynamodbput

Using NodeJS promise to create records in DynamoDB


I want to create a new record in dynamoDB using NodeJS functions, but before I need to create a transaction with stripe API and after I store the information in DynamoDB.

I wrote these lines of code, but nothing will be inserted in dynamo. Any ideas?

import * as Stripe from "stripe";
const randomBytes = require('crypto').randomBytes;

const AWS = require('aws-sdk');
AWS.config.update({ region: 'eu-central-1' });

import { SECRET_API_KEY } from "../config";

/** Config */
const stripe = new Stripe(SECRET_API_KEY);

const ddb = new AWS.DynamoDB.DocumentClient();
AWS.config.update({ region: 'eu-central-1' });

export async function createCustomerAndSubscribeToPlan(
  stripeToken: string,
  email: string,
  productPlan: string
): Promise<any> {
  // create a customer
  const customer = await stripe.customers.create({
    email: email,
    source: stripeToken
  });


  // retrieve created customer id to add customer to subscription plan
  const customerId = customer.id;
  // create a subscription for the newly created customer
  const subscription = await stripe.subscriptions.create({
    customer: customerId,
    items: [{ plan: productPlan }]
  });

  /** Insert inside S3 Storage the user and validity */
  const record = await recordSub(stripeToken, email, productPlan);

  return subscription;
}

function recordSub(stripeToken, email, productPlan) {

  const subrisctionId = toUrlString(randomBytes(16));
  console.log('Putting inside db ' + subrisctionId);
  return ddb.put({
      TableName: 'OG_SUBRISCPTIONS',
      Item: {
          OG_SUBRISCPTIONS_ID: subrisctionId,
          ProductPlan: productPlan,
          RequestTime: new Date().toISOString()
      }
}).promise();
}

function toUrlString(buffer) {
    return buffer.toString('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=/g, '');
}

Thanks to @Wyetro i've also modified my previous code adding AWS configuration and moved my lambda function in the same AWS region of DynamoDB. I've also enriched my LambdaRole with AWS CloudWatch and now i've this error message:

2020-04-23T06:49:40.673Z    79140900-41ff-41aa-bab6-7d1ca6aabec2    INFO    Putting inside db NRc_xX_dhep6XSbts51Sxw
2020-04-23T06:49:40.691Z    79140900-41ff-41aa-bab6-7d1ca6aabec2    ERROR   (node:7) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
END RequestId: 79140900-41ff-41aa-bab6-7d1ca6aabec2
REPORT RequestId: 79140900-41ff-41aa-bab6-7d1ca6aabec2  Duration: 1851.16 ms    Billed Duration: 1900 ms    Memory Size: 1024 MB    Max Memory Used: 126 MB Init Duration: 593.69 ms    

After some research in AWS forum, i found the problem inside the aws-sdk module version, upgraded it the problem persist. No error in CloudWatch but anything inside the table.

START RequestId: 61b612b4-b9a1-40ce-b6e8-5d75493ba8ea Version: $LATEST
2020-04-23T07:52:08.224Z    61b612b4-b9a1-40ce-b6e8-5d75493ba8ea    INFO    Putting inside db EG8UiaSElpfis7MyWanBTg
END RequestId: 61b612b4-b9a1-40ce-b6e8-5d75493ba8ea
REPORT RequestId: 61b612b4-b9a1-40ce-b6e8-5d75493ba8ea  Duration: 2039.72 ms    Billed Duration: 2100 ms    Memory Size: 1024 MB    Max Memory Used: 129 MB Init Duration: 631.94 ms    

Solution

  • The issue is that recordSub is not returning a promise. You need to add .promise() to make the DocumentClient put a promise:

    return ddb.put({
          TableName: 'OG_SUBRISCPTIONS',
          Item: {
              OG_SUBRISCPTIONS_ID: subrisctionId,
              ProductPlan: productPlan,
              RequestTime: new Date().toISOString()
          }
    }).promise();
    

    It also doesn't look like you've set your AWS region.

    AWS.config.update({ region: 'us-east-1' }); // Set to whatever your region is
    

    Additionally, are you sure your table name and id is correct? SUBRISCPTIONS is not the correct spelling of SUBSCRIPTIONS.