How to build a fast and reliable community mapping tool with GatsbyJS and Firebase
What acrazy time to be alive. Following the coronavirus pandemic, I became aware how crucial a connected community can become once everybody has to stay in self-isolation.
About this project
This community map has initially been developed by Simon Huwiler, who works as a developer for the Zurich editorial team at Tages-Anzeiger, which is lead by Mario Staeuble. The map was built on the TA Interaktiv React Base which was designed and maintained by Kaspar Manz for the Tages-Anzeiger Interaktiv Team over the last couple of years. I’m utterly grateful for all money and time that has been spoken and invested to build this map tool––once it was published, I was granted access to the repository and transformed it into this open source GatsbyJS site––which I’ll explain to you in this article.
Having been a part for the Interaktivteam at Tages-Anzeiger in Zurich for a few years, their project called “Zurich Delivers” instantly caught my attention. Its main piece is an interactive map (I know, nobody likes interactive maps anymore), filled with home-delivery services available in Zurich:
Let’s begin!
So far, so good. Marc Brupbacher, who is leading the Interaktivteam, justified the need for an interactive map on Twitter. “We all need to support near-by services, that’s why we put together a map — even if I personally hate interative maps”.
I then started adapting the project for the needs in our small community in Muizenberg, South Africa, where we’re now just about to get ready to isolate against the coronavirus. This is the result: https://www.whozinberg.org
The feedback inside the community was really good––what made me think that this should become an open source project, so other developers in other neighbourhoods can set it up themselves. And here we are––follow the tutorial and set up your own “Community Isolation Map”.
What the map, what it is not:
- It’s made for small communities––so it stays manageable for few people to run it, rather than having over-engineered solutions that get out of hands quickly.
- It’s currently not optimal for finding help if someone is in need because it’s showing all the information on a map. I have the intention to build a “I need help” function soon, but this will be covered in a second tutorial.
- It’s built on a solid foundation using free web technolgies and thus should be expendable in any direction you want it to go––and free to run.
- It’s free for all––and here to help. Let’s support the communities!
The steps we’ll walk through:
- Clone the repository from Gitlab
- Install packages, get all up and running with Gatsby JS using Node
- Create and configure a Google Firebase Realtime Database
- Get your own token for the Map on Maptiler (we’ll use Mapbox GL)
- Adjust map and content settings to fit your community
Get your own copy by either cloning or forking the project from Gitlab:
https://gitlab.com/marc.fehr/community-isolation-map
Node environment
Because I often ran into problems with different Node and NPM versions, I implemented a file called .nvmrc in the main folder of the project. If you have the Node Version Manager (nvm) installed, the first thing you should do, is
# Change into your projects folder
cd community-isolation-map# Set up Node to use the version defined in .nvmrc
nvm use
Install project dependencies
I’m using yarn, but if you’re the npm kind of person, this will also work:
# Install using yarn
yarn install# Install using npm
npm install
This will take a little while, but should work without any errors. If so, you’re ready to run into some trouble trying to start the Gatsby site!
Starting up Gatsby JS (…or at least we try)
You can now try to run, but you’ll see few errors in the gatsby-config.js. We’ll have to fix those first. But we see in the error, at least, that it’s about the gatsby-config.
# Start local development server
gatsby develop# Result:We encountered an error while trying to load your site's gatsby-config. Please fix the error and try again.TypeError: Cannot read property 'replace' of undefined
This file is in the main directory of your project (gatsby-config.js)
The gatsby-config.js
The first couple of lines can stay as they are for now, but you’ll eventually want to change the trackingId on line 40 to your own Google Analytics tracking project, if you want to use Google Analytics:
# Change to your own Google Analytics account
trackingId: "UA-XXXXXXXXX-X",
Then we’ll have a closer look to line 47 where it says
databaseURL: process.env.FIREBASE_URL
I am using these process.env variables to make sure that any sensitive credentials from services we’re using are never going to be published via Git. In the .gitignore file, you’ll see that there is a rule to ignore all files starting with .env, which is good.
Later, when you’ll deploy this website, the bots on Netlify (or Gitlab, or whatever service) will be given these variables––they won’t get it from your repository.
But if you’re working on your localhost, using gatsby develop like we just tried, you can write all these .env variables into a file you’ll have to create yourself now. It should be called .env.development
# Create new file in the main directory called
.env.development
Now define all the variables you will need for this project, like this, in your .env.development file:
FIREBASE_URL=
FIREBASE_TYPE=
FIREBASE_PROJECT_ID=
FIREBASE_PRIVATE_KEY=
FIREBASE_CLIENT_EMAIL=
FIREBASE_CLIENT_ID=
FIREBASE_AUTH_URI=
FIREBASE_TOKEN_URI=
AUTH_PROVIDER_X509_CERT_URL=
CLIENT_X509_CERT_URL=
That’s it for now, let’s go online to set up a database.
Firebase Realtime Database
Go to https://firebase.google.com/products/realtime-database and sign in with your Google Account. Set up your own Firebase Realtime Database by clicking “Go to Console’” (top right of the window), or click here. Start with “add project”, give it a name and click through the steps. You can decide whether you want the database to be linked to any of your Google Analytics accounts or not.
On the left hand side, click on Database, then choose Realtime Database and click “Create Database”:
You can start in “locked mode” for now, and then go to “Rules” to adjust the security settings as follows, and press Publish:
Go back to the Data tab, and enter any random value to where it says null, otherwise the database will be deleted [because it is empty]:
Also, take the URL just above that and add it to your local .env.development file as FIREBASE_URL:
FIREBASE_URL=https://whozinberg.firebaseio.com/
Next, click on the settings wheel, top left, and choose “Users and permissions”, to create a user that can later access the data in Gatsby via GraphQL:
Go to “Service Accounts”, and click on “Generate new private key”:
Confirm, and your browser will download a .json file with your credentials. This is how it looks like:
Go ahead and copy-paste the values from this file into the .env.development file we created earlier. The first line was already filled few steps before. Make sure you don’t forget anything, save. Important: Don’t copy the “, only the bare values, without anything.
Last step, we import some example data into our database, just to make sure that the Gatsby JS project will find some data, otherwise it will throw an error. Take the file from your repository in ~/src/data/exampleData.json or download it from here.
In Firebase, click on Import JSON, choose the testData.json file, and confirm.
Voilà, this is how your database now looks. Please note, importing JSON does always overwrite the database. Make sure you exported the JSON before in case you will need it again.
Note: As you see, this entry has approved: true, but later, new entries will be entered with approved: false. This is how you will have control over which entries are online, and which are not. All those who are set to approved: true will be visible after a next deploy of the website.
Start Gatsby Localhost again
Now you’re ready to give Gatsby JS another go. Back in your terminal, go to the main folder of your project, and
# Start Gatsby development server
gatsby develop
And, besides few es-lint warnings, you should see:
Go and check http://localhost:8000/ in your browser, and you should see one first data point on the map:
That’s it, you did it! Now, let’s try to also add a new point to the database. In your browser, click on the link “Add more information to the map” or add /add to the url like: http://localhost:8000/add––activate the map, set a point, fill in some data, and click “Send form”.
And, as you can see, my data has been saved in my database — there are now two entries:
And, as mentioned before, the new entry does have the approved: false state.
Maptiler Access Token
The repository is shipped with some Maptiler keys, but please don’t use those. Every project should have its own Maptiler Access Token.
Go to Maptiler, create an account, login, and create a key (under “keys”, left hand side under “Account”). Copy this key and replace it in your repository. Hint: You can also restrict access to your key by adding the domains the traffic is allowed to come from.
In your repository, go to ~/src/data/map-styles.js and add the token to:
Adjust the app to your needs
Now it’s all about finding out what your community needs. You can start with changing all the details about the project in gatsby-config.js, play around with the ~/components/categories.js (and the categories.css), or whatever.
Update: Also, make sure you set the boundaries for your neighbourhood correctly. Check the file gatsby-config.js in the main folder to set the boundaries for the map itself. Further, go to:
~/src/data/reverse_cpt_boundaries.js
… and adjust the mask that’s overlaying the map. It’s done with the “turf” npm package, you can drop any valid geoJSON polygon and it will be automatically inverted and used as a map overlay. In the example, it’s simply a rectangle that masks everything but the Muizenberg area in Cape Town:
Deploy the website to Netlify
Now it is all running on your localhost, but it’s not on the interwebs, yet. To do so, you’ll have to create a new repository on Gitlab (or Github), push the whole project folder up.
Then, sign up on Netlify, a platform for hosting static websites. Netlify has got a free tier, you’ll be given 100GB traffic each month without paying. Which I think is amazing.
On Netlify, start a new project, link it to your Gitlab (or Github) repository. Click “New Site from Git”. Go through the steps, set the master branch for triggering deploys. gatsby build as deploy action and public/ for the directory:
Netlify is now deploying your site from your Git repository. And, it will re-deploy it after every push to the master branch. But for now, the first build will fail — because we didn’t specify our .env variables on Netlify. To do so, go to Settings > Build & Deploy > Environment, and add all the variables you have inside the local .env.development file. Netlify will use these while building your page, but people won’t ever see them:
Go back to deploys, and trigger a re-deploy of your site, after all environment variables have been declared:
Once Netlify is done, you’ll se an URL for your project. Go, check it out. You can now even add custom domains to Netlify (point your nameservers there or add CNAME DNS entries to your hoster), and also use free SSL certificates.
This is now online. Well done! Every new entry will have to be approved manually in Firebase. Go to your Firebase database view, check through the new entries, and if you want them on the map, change the approved: false to true. Once done, re-deploy your website, and Netlify will grab a new set of data from Firebase.
Again, every push to the master branch on Gitlab (or Github) will also trigger a deploy. Always make sure that the deploys don’t fail, otherwise you’ll not see the updates :)
Thanks for sharing — let’s help our local communities! Any feedback on this is very welcome.
Spread the map––further instances I know of
Thanks to the open source community ❤ for adapting this community map for their local neighbourhoods. Check out these amazing projects:
St.Gallen hilft––https://www.helfen.sg/
Zizers hilft!––https://zizers-hilft.netlify.com/
Zäme starch––https://zaemestarch.ch/
Chur hilft Chur––https://churhilftchur.ch/
––If you build one, too, let me know! Stay safe everyone!