# Display AWS S3 files from signed URLs

This example explains how to display pictures stored in an AWS S3 bucket, from signed URLs.

Below we have a collection `places` with a field `pictures` which is an array of strings containing the names of files stored in an S3 bucket on AWS.

We use then a smart field `s3Pictures` that is an array of return values from calls made to S3 to get signed URLs from the files present in `pictures` field.

![](https://2793709227-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M0vHiS-1S9Hw3djvoTw%2F-MgfT8WUThp2jaLH1dX-%2F-MgfVStGvU5qFLZvOQoe%2Fimage.png?alt=media\&token=0e815c48-5b95-40ef-8f31-6bd927567866)

## Requirements

* An admin backend running on forest-express-sequelize
* An AWS S3 bucket with access credentials
* The [aws-sdk](https://www.npmjs.com/package/aws-sdk) npm package

## How it works

### Directory: /models

This directory contains the `places.js` file where the `places` model is declared.&#x20;

{% code title="places.js" %}

```javascript
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
    const Places = sequelize.define('places', {
    name: {
      type: DataTypes.STRING,
    },
    address: {
      type: DataTypes.STRING,
    },
    pictures: {
      type: DataTypes.ARRAY(DataTypes.STRING),
    },
  }, {
    tableName: 'places',
    underscored: true,
    timestamps: false,
  });

  return Places;
};
```

{% endcode %}

### Directory: /services

This directory contains an `s3-helper.js` file, where the method to get the signed URL from S3 is defined. We use the `aws-sdk` npm package to connect to the bucket storing the pictures.

{% hint style="info" %}
You need to configure your AWS credentials inside your app to get access to your bucket. You can read more about it in the AWS documentation [here](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html).
{% endhint %}

{% code title="" %}

```javascript
const AWS = require('aws-sdk');

// Retrieving the AWS credentials from `.env` file
AWS.config.update({
  region: process.env.AWS_REGION,
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
});

function getS3SignedUrlById(fileId) {
  const s3Bucket = new AWS.S3({ params: { Bucket: process.env.S3_BUCKET } });
  return s3Bucket.getSignedUrl("getObject", {
    Key: fileId,
    Expires: 60 * process.env.AWS_S3_URL_EXPIRE_MINS,
  });
}

module.exports = getS3SignedUrlById;
```

{% endcode %}

### Directory: /forest

This directory contains the `places.js` file where the smart field `s3Pictures` is declared.&#x20;

In the get function, we iterate on the pictures array to get the signed URL for each file name and then return an array with the signed URLs.

You can then use the [file viewer widget](https://docs.forestadmin.com/documentation/reference-guide/fields/customize-your-fields/display-widgets#file-viewer) to preview the pictures.

{% code title="places.js" %}

```javascript
const { collection } = require('forest-express-sequelize');
const getSignedUrlById = require('../services/s3-helper');

collection('places', {
  actions: [],
  fields: [
    {
      field: 's3Pictures',
      type: ['String'],
      get: (place) => {
        if (place.pictures) {
          const s3pictures = place.pictures.map((pic) => getS3SignedUrlById(pic))
          return Promise.all(s3pictures)
        }
        return null;
      },
    },
  ],
  segments: [],
});
```

{% endcode %}

###
