How to Build a Quote Gallery App using Google Sheets
Image loading...
Developers commonly use SQL or NoSQL databases to store and organize data. But do you know that there's a more lightweight, flexible and intuitive alternative? It's called a spreadsheet, a very familiar type of document for most people.
In this beginner-friendly tutorial, we shall build a simple quote gallery app. The app can do the following:
- Fetch quote data from "database"
- Display fetched data in app
- Add new quote and update the "database"
The "database" that we are using in this app is Google Sheets! That's right, no fancy SQL or NoSQL databases, just the simple spreadsheet we all know. Let's begin!
Getting Started
Before getting into the coding part of this project, we must first have the following ingredients:
- A Google Developers account
- A Google Drive account
- Node.js and npm installed in your device
Step 1: Connect Google Sheets API
First, we need to connect the Google Sheets API to our app. So head to https://console.developers.google.com/ to sign in or create a free Google Developers account.
Then, add a new project and name it appropriately.
Image loading...
After creating the project, you will see the dashboard. Click the Enable APIs and Services button as shown in the screenshot below.
Image loading...
Then, you will be redirected to the API Library. Scroll down and click on Google Sheets API.
Image loading...
Once you click that, you will be taken to the page shown below. Create your credentials.
Image loading...
Follow the screenshots below to answer the questions. Part 1 is below.
Image loading...
Here is Part 2.
Image loading...
A JSON file (credentials.json) will then be downloaded to your machine. This credentials.json file will be used to connect our app to the API.
Important: You must save this credentials.json file safely because you won't be able to regenerate it once you lose it. Unless you disable the API and restart everything.
Copy the Service Account ID. We will need it in the next step.
Step 2: Create a Google Sheets
Now, let's create a Google Sheets. Log into your Google Drive account to create a Sheets document.
Image loading...
On your Sheets, give each column a name and add some data like it's a database. In my example, I have the Quotes, Quoter and Category columns.
Image loading...
Remember the Service Account ID we copied earlier? Click on the Share button on the top right of the Sheets window and add that ID as an Editor, as shown in the image below.
Image loading...
The final task to do in this window is the Sheets ID, which is located in the URL of the Sheets.
Image loading...
Copy this Sheet ID because we will need it to tell our app which Sheets to access.
Step 3: Set up React App
Make sure you have Node.js or npm installed, then create a new React project with:
bashnpx create-react-app quote-gallery
$
Then install google-spreadsheet with:
bashnpm install google-spreadsheet
$
Next, copy your credentials.json file into the app's src folder. Import it in App.js:
jsconst creds = require('./credentials.json')
Step 4: Read Data from Sheets
Our app is finally ready to use our Sheets as a database. To read data from our Sheets, let's first create an array called rows
, where we will save all the data in rows from our Sheets.
jsconst [rows, setRows] = useState([]);
We initialize it as an empty array. Then, we create a getSheet() function.
This function will:
- Get the Sheets doc we want by its ID we copied earlier
- Initialize Authorization to access the Sheets using our
creds.client_email
andcreds.private_key
- Loads data from our Sheets doc. Then, get data from the first worksheet and get all its rows.
- Finally, we save the retrieved rows to our
rows
array which we initialized earlier.
jsasync function getSheet(){ //1. const doc = new GoogleSpreadsheet('Sheet ID'); //2. await doc.useServiceAccountAuth({ client_email: creds.client_email, private_key: creds.private_key, }); //3. await doc.loadInfo(); const sheet = doc.sheetsByIndex[0]; //get 1st worksheet const rows = await sheet.getRows(); //get all its rows //4. setRows(rows); }
If we console.log(rows), we can see that the data retrieved is an array of GoogleSheetRows and each element contains its own properties such as its column names: Category, Quoter, Quotes and their respective values.
Image loading...
So now that we have successfully retrieved all our row data, our app should display this data nicely.
Step 5: Displaying Data
If we want to get the quote, quoter and category of our first row, it is simply: rows[0].Quotes, rows[0].Quoter and rows[0].Category. So to do this for every row in our rows
array, we can use rows.map()
. Let's see how this works.
You can choose any CSS library or framework to do this step. For this tutorial, I am using Material UI.
I created a Grid component as the container that will contain all the data. Inside this component is the rows.map()
function which returns each row in the format like so:
Image loading...
Here's what it looks like in code:
js<Grid className= "container" container justify="center"> {rows.map((row, index)=>{ return( <Grid className= "card" key={index} xs={12} sm={3}> <p>{`${row.Quotes}`}</p> <p style={{fontStyle:"italic"}}>{`- ${row.Quoter}`}</p> <Chip className= "chip" label={`${row.Category}`}/> </Grid> ) })} </Grid>
And the result will be:
Image loading...
Each row data is organized into the style we wanted. With the Quotes, Quoter and Category displayed accordingly for every element in rows
.
But a database is not that useful if it's read-only right? Let's implement adding a new quote and updating the Sheets from our app.
Step 6: Add a New Quote
In the app, create a simple form with the values we need to update our Sheets database.
Image loading...
Then, initialize 3 states that I will need to add a new row: category, quoter and quote.
jsconst [category, setCategory] = useState("Category"); const [quoter, setQuoter] = useState(""); const [quote, setQuote] = useState("");
In the button Add New Quote, let's create the handler addNewRow() function which will execute onClick.
js<Button onClick={addNewRow}>Add new quote</Button>
This function will:
- Check if all the fields are filled with values
- Get our Sheets by its ID
- Authorize with credentials
- Loads the Sheets doc. Get the first worksheet.
- Add the new row by passing an object with the 3 states: quote, quoter and category as the values, and their respective column names as the object keys.
- Retrieve the new rows data and update the
rows
array.
In code:
jsasync function addNewRow(){ //1. if(category!=="Category" && quote !== "" && quoter !== "" ){ //2. const doc = new GoogleSpreadsheet('Sheet ID'); //3. await doc.useServiceAccountAuth({ client_email: creds.client_email, private_key: creds.private_key, }); //4. await doc.loadInfo(); const sheet = doc.sheetsByIndex[0]; //5. await sheet.addRow({ Quotes: quote, Quoter: quoter, Category: category }); //6. const rows = await sheet.getRows(); setRows(rows); //reset values setQuote(''); setQuoter(''); setCategory('Category'); alert('Thank you for adding a quote! :)'); //show message }else{ alert("Some data is missing!"); } }
Let's see how it works in our app!
Image loading...
It works perfectly. We can go to our Sheets and check that the data has indeed been added as a new row and that the new quote appears in the app.
Conclusion
In this tutorial, we can see how easy it is to set up and have Google Sheets as a convenient database to store and retrieve data in an organized manner. While it is definitely a useful tool, there are currently some limitations to the Google Sheets API.
According to this [article](https://dev.to/hacubu/how-to-use-google-sheets-as-a-database-responsibly-3ohk nofollow), Sheets has a hard limit of 5,000,000 cells (including blank cells), so any data larger than that would not fit. Also, queries became impractically slow around the 500,000 cell mark which makes using Sheets quite a poor choice at handling large amounts of data.
Still, this is perfectly fine choice for small apps like this quote gallery app. Thanks for reading this article. Please like and share if it is helpful. For more information on this tutorial, feel free to visit its repo and demo in the links below. Cheers!
- See repo: https://github.com/victoria-lo/quote-gallery
- See demo: https://quote-gallery.vercel.app