Managing payments in your app: setting up inventory — the code

Jen Person
Google Cloud - Community
5 min readJul 13, 2020

See how to implement item uploads to Cloud Firestore

Feet in colorful socks resting on a desk in front of a computer
Set up your store, then sit back and let the sock profits roll in. source

Are you new to this series? Check out the first blog for an introduction and a table of contents!

Get caught up

If you’re interested in the rationale behind this code, you can find out all about it in the last post!

Assuming you already have read it, I’m basically going to dive into the implementation. To briefly summarize, we don’t want items to be hard-coded into our HTML. Instead, items will be stored in Cloud Firestore and downloaded when the website is accessed. But the items come with images — of course folks want to see what they’re going to buy! — so we need a place to store those as well. We use Cloud Storage to upload the item images, and then generate a unique download URL for each one so it can be viewed publicly.

Google Cloud Storage provides the perfect place to store sock pattern images

Get the project

Each step of the project can be found on GitHub. Download or clone the repo to follow along. Today, I’m walking through step 0: setting up inventory. Navigate to the part-0-set-up-inventory/upload-function folder and take a look at the contents.

  • an index.js file
  • a package.json file
  • a product_img folder

The index.js file contains the code to upload the inventory items. The package.json file contains the Node.js packages we need. The product_img folder contains the beautiful images of the socks.

Animated graphic of sock with apple pattern
Ever so beautiful!

Set up the project

Before we run the code, there are a couple of setup steps.

First, start with a new or existing Firebase project with Cloud Firestore initialized.

Then, install the required npm packages.

npm install

The function we use to upload the items uses the Firebase Admin SDK to access Cloud Firestore. In order to authenticate, you will need to download a service account key. Keep in mind that this allows access to all of your Firebase products, so be sure to keep it safe and never store it in a public repository.

Set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the file path of the JSON file that contains your service account key. This variable only applies to your current shell session, so if you open a new session, you will need to set the variable again, but this is unlikely to come into play since you only have to run this function once.

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

You’ll also need the name of your Cloud Storage bucket. You can hard-code this if you wish, but since we’ll need it for future parts of the project, I find it’s more convenient to create an environment variable.

export STORAGE_BUCKET="your-project-name.appspot.com"

Now the function is ready to be run! But before we run it, let’s take a look at what it does. It’s always good to know what you’re getting into!

First, we import and initialize the Firebase Admin SDK using those default credentials we just set in the terminal. Then, we create an instance of Firestore and an instance of your Cloud Storage bucket.

const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.applicationDefault(),
storageBucket: process.env.STORAGE_BUCKET
});
const db = admin.firestore();
const bucket = admin.storage().bucket();

Then, there is an array of the sock patterns.

let items = [
{
name: 'apple',
description: 'For the apple lover in your life',
price: 999
},
{
name: 'donut',
description: 'Some super sweet socks',
price: 999
},
{
name: 'stripes',
description: 'Classy and classic design',
price: 599
},
{
name: 'blue',
description: 'Simple, yet shockingly sophisticated',
price: 599
}
]

Next comes the setData() function, which takes the array of the shop’s items and uploads the data to Cloud Firestore.

async function setData() {
for (item of items) {
console.log(item); // it’s fun to see something on the screen when you run a function
let thisItem = item;
const filename = `${item.name}.png`;
try {
// upload the image to Cloud Storage
await bucket.upload(`product_img/${filename}`, {
// Support for HTTP requests made with 'Accept-Encoding: gzip'
gzip: true,
metadata: {
cacheControl: ‘public, max-age=31536000’,
},
});
const config = {
action: 'read',
expires: '03–17–2025'
};
// get a signed URL so the image can be viewed publicly
const url = await bucket.file(filename).getSignedUrl(config);
// add URL to the data about the item
thisItem.images = url
// upload object data to Cloud Firestore
await db.collection(‘socks’).doc(item.name).set(thisItem);
} catch (error) {
console.error(error);
}
}
}

We also log the item names and objects so you have something to look at while running the function. Alright, without further ado, let’s run this!

node index.js

To ensure the inventory is successfully uploaded, check the Firebase Console.

Ta-da! And that was almost less work than adding the items from the console if you don’t count the time I spent coding it. But hey, it’s definitely less error-prone.

Next Steps

I can’t believe how perfect this image is. source

Now this is clearly not practical or convenient for making regular updates. What we really need is a frontend that makes adding items easier. We call that ‘foreshadowing’. But for now, this is what we need to get the project up and running!

Next:

--

--

Jen Person
Google Cloud - Community

Developer Relations Engineer for Google Cloud. Pun connoisseur.