skip to Main Content

everyone. I’m here to ask a help with Amazon DynamoDB configuration in Node.js + Typescript backend.
I’m trying to create a record to the dynamoDB database.
I’m using Node.js + Express for the backend and faced this error when I try to access DynamoDB

Error: Resolved credential object is not valid
    at SignatureV4.validateResolvedCredentials (D:morgan (2)React + Node.jsDWQservernode_modules.pnpm@[email protected][email protected]:182:19)   
    at SignatureV4.signRequest (D:morgan (2)React + Node.jsDWQservernode_modules.pnpm@[email protected][email protected]:107:14) {
  '$metadata': { attempts: 1, totalRetryDelay: 0 }
}

Here is my code.

// dbconfig.ts

import { DynamoDBClient } from "@aws-sdk/client-dynamodb";

// Create Amazon DynamoDB service client object
const ddbClient: DynamoDBClient = new DynamoDBClient({
  region: process.env.REGION,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
  },
});

export { ddbClient };
// ddbDocClient.ts

import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
import { ddbClient } from "./dbconfig";

const marshallOptions = {
  convertEmptyValues: false, // Whether to automatically convert empty strings, blobs, and sets to `null`
  removeUndefinedValues: true, // Whether to remove undefined values while marshalling
  convertClassInstanceToMap: false, // Whether to convert typeof object to map attribute.
};

const unmarshallOptions = {
  wrapNumbers: false, // Whether to return numbers as a string instead of converting them to native JavaScript numbers.
};

// Create the DynamoDB document client.
const ddbDocClient = DynamoDBDocumentClient.from(ddbClient, {
  marshallOptions,
  unmarshallOptions,
});

export { ddbDocClient };
// UserController.ts

static async register(req: Request, res: Response) {
    const parsedData: RegisterUserInput = RegisterUserSchema.parse(req.body);
    const { confirm, creditNumber, expireMonth, expireYear, creditCode, creditZip, creditOwner, ...filteredInput } = parsedData;
    const hashedPassword: string = await bcrypt.hash(filteredInput.password, 12);

    // Query command finds user by email
    const queryParams: QueryCommandInput = {
        TableName: "users",
        KeyConditionExpression: "email = :email",
        ExpressionAttributeValues: {
            ":email": filteredInput.email,
        },
    };

    // Create a new user data
    const putParams: PutCommandInput = {
        TableName: "users",
        Item: {
            _id: uuidv4(),
            ...filteredInput,
            password: hashedPassword
        }
    };

    await ddbDocClient.send(new QueryCommand(queryParams))
        .then(existUser => {
            // If the user email exists in the database
            if (existUser.Items && existUser.Items.length > 0) {
                res.status(200).json({
                    success: false,
                    message: "User email already exists.",
                });
            } else {
                // Create a new user if it doesn't exist
                // const data = await ddbDocClient.send(new PutCommand(putParams));

                res.status(201).json({
                    success: true,
                    message: "Successfully registered!",
                    result: data,
                });
             }
        })
        .catch(error => {
            console.log(error);

            // Return error response from the server
            res.status(500).json({
                success: false,
                message: "Internal Server Error",
                error
            });
        });
}

I can be sure that I have set env variables correctly.
Please help me with that.

2

Answers


  1. Chosen as BEST ANSWER

    I solved it by myself. It was because I received empty env variables. I set dotenv config and got them successfully.

    import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
    import * as dotenv from 'dotenv';
    
    dotenv.config();
    
    // Create Amazon DynamoDB service client object
    const ddbClient: DynamoDBClient = new DynamoDBClient({
      region: process.env.REGION,
      credentials: {
        accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
      },
    });
    
    export { ddbClient };
    

  2. I would first strongly advise you from coding credentials directly into a client, you should resolve them from role ideally.

    However, the exception you are seeing is because you are passing the wrong values as your credentials. My suggestion is to check the values of
    process.env.AWS_ACCESS_KEY_ID! & process.env.AWS_SECRET_ACCESS_KEY!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search