Using Notion to Create a User Database: Part I
đź“„

First published on .

By the end of this tutorial we will have created a Notion Database that we can add users to using the Notion Javascript API.

Getting Started

  1. Create a Table in Notion to hold your data. We’re going to create a table to keep track of our users. I named mine “Users” and gave it a Username, Email, and Password property.
  2. Create an integration in notion and copy the secret token for your integration. You’ll need this later to access Notion with our script.
  3. Share the table you created with your Integration. It should show up below the list of users when you select Share.
  4. While you’re there, copy the database ID, we’ll need that later. It is the string following the last / character and before the ? character
  1. Create a project, using yarn init in an empty folder to initialize your node.js project
  2. Install the @notionhq/client npm package. This is the Javascript API for notion, and we’ll use it to create the functions we use for this project.
    yarn add @notionhq/client
  3. Finally create an index.js file, this will be how we

Creating a User

Now we’re ready to interact with our Notion database. In Notion databases are made up of pages, so to add a user to our database we’re going to need to create a page in the database. To do this we will need the users Username, Email, and Password.

Here is the function that will Create our User. It uses the notion.pages.create({}) function and passes an object with the parent database and the properties we wish our created object to have.

const { Client } = require("@notionhq/client");
//Initializing a client
const notion = new Client({
  auth: SECRET_TOKEN,
});

let username = "testuser";
let email = "me@myaddress";
let password = "SuperS3cr3t!";

async function CreateUser(username, email, password) {
  let foundUser = await CheckUser(username);
  const response = await notion.pages.create({
    parent: { database_id: DATABASE_ID },
    properties: {
      Username: {
        id: "title",
        type: "title",
        title: [{ text: { content: username } }],
      },
      Email: { id: "Sg`s", type: "email", email: email },
      Password: {
        id: "AMxG",
        type: "rich_text",
        rich_text: [{ type: "text", text: { content: password } }],
      },
    },
  });
  console.log(`SUCESS: User successfully added with pageId ${response.id}`);

  async () => {
    CreateUser(username, email, password);
  };
}

As you can see the Username is using the title property, the Email is using Notion’s email property, and the password is using Notion’s rich_text property but only adding a plain-text component with the content of the password parameter.

After running this script our Notion table looks like this:

Success!

The problem is that currently we are storing our passwords in plain text which is NOT a good idea. In order to keep our users information private we are going to add a step to the CreateUser function where we will hash the password of the user before passing the hashed password to Notion for storage.

In order to hash our password we are going to use the bcrypt package. Later down the line when we implement a login functionality we can compare the hash of the password the user attempts to login with to the hash of the stored password in the database.

const bcrypt = require("bcrypt");
...
let hashedPassword = await bcrypt.hash(password, 10);

We also need to implement a way to check whether or not a username already exists in our database. In order to do this we will use notion.databases.query({}) and pass in the DATABASE_ID of our users database and our filter conditions - in this case we are looking for entries where Username is equal to the parameter of the function

async function CheckUser(username) {
  const response = await notion.databases.query({
    database_id: DATABASE_ID,
    filter: { property: "Username", text: { equals: username } },
  });
  if (response?.results[0]?.id) {
    return response.results[0].id;
  } else {
    return false;
  }
}

Now we can add this funciton to our CreateUser function to first check whether a user exists before we add it to the database. Once we do that Our finished CreateUser account will look like this:

async function CreateUser(username, email, password) {
  let foundUser = await CheckUser(username);
  if (!foundUser) {
    let hashedPassword = await bcrypt.hash(password, 10);
    const response = await notion.pages.create({
      parent: { database_id: DATABASE_ID },
      properties: {
        Username: {
          id: "title",
          type: "title",
          title: [{ text: { content: username } }],
        },
        Email: { id: "Sg`s", type: "email", email: email },
        Password: {
          id: "AMxG",
          type: "rich_text",
          rich_text: [{ type: "text", text: { content: hashedPassword } }],
        },
      },
    });
    console.log(`SUCESS: User successfully added with pageId ${response.id}`);
  } else {
    console.log(
      `ERROR: User already found with the username ${username} and pageId ${foundUser}`
    );
  }
}

Contact

Content is copyrighted 2019-2023 © D.S. Chapman. This site was built using GatsbyJS. Code for this website is open source and available on Github