I’ve been unemployed for the past month, so in that time I’ve decided to work on various side projects and potential businesses. A lot of that time was spent building things with various languages (like Python and Ruby) that I’ve not worked with professionally. I also devoted quite a bit of time to learning all about React and React Native.
The first project I’ve been working on is SoundFair, a podcast app allowing listeners and podcasters an opportunity to get better connected. It’s a more serious project, so I’ve been very concerned with getting it “right”. I’m building the mobile app in React Native, and I’ve been finding the audio portion to be the biggest roadblock in completing it.
Since my layoff, there’s been a lot of time searching for a new gig, with interviews and phone calls and flights to other cities… and SoundFair has stopped getting as much attention as it should. So I thought, “I need a quick win”. Something I can start and finish quickly, with the initial idea of being a 24 hour project. But I needed an idea.
Over the summer, we’ve been doing a “point reward” system with my son, so that for various preset tasks, he gets a certain amount of points. Those points can then be exchanged for either an allowance or something he wants to buy. To this point, it’s all been tracked on printed paper. So I decided I was going to build an app that would replace the paper.
Step 1: Specs
I knew it needed a login/auth system, and that both my wife and I would need separate accounts, but could both manage the same kids. It would also need a way to add/remove/edit kid information, add/remove/edit tasks for each kid, let you click on a task (mark it as complete and award those points), redeem/remove points for whatever reason, and view a list of all the completed tasks and redemptions.
I already knew I was going to build it in Laravel (as the API backend) and React Native, since those would be the quickest. And after writing out the specs, I saw obvious “objects” I would build around.
Step 2: API and Database Architecture
Laravel has a simple auth system built in, so that took care of a User
object. Then I decided on Kid
, Task
, and Reward
as the other objects. The User
would be related to the Kid
using a join table, so one Kid could have multiple parents (User
). A Task
would belong to one Kid
and a Reward
would belong to a Task
. With all that in mind, I was able to quickly create all the Eloquent Models and migrations I needed.
Using the specs, it was also very apparent that I would need some fairly common CRUD endpoints, like POST /kid
to add a kid, GET /kid/{kid_id}
to retrieve a single kid’s info, PUT /kid/{kid_id}
to update their info, and DELETE /kid/{kid_id}
to remove them. It would also need similar endpoints for tasks and rewards. I also had a few not-REST-ful endpoints, like kid/{kid_id}/redeem
to allow for points to be subtracted.
I decided to skip Controller creation for the project, so everything is done in route closures.
From there, I wrote out all the endpoint code I needed, using the Eloquent models directly. And added a Middleware that would make sure the authenticated user actually had permission to access the specific kid endpoints.
Honestly, the basic endpoint functionality was complete within an hour and a half. There were a few tweaks as I worked on the mobile side, but most of it was knocked out very quickly.
Step 3: React Native
I decided to use React Native Expo to create the app, testing it specifically for Android since that’s what I use. The only libraries I used were React Navigation and Axios, as those are fairly standard across the RN ecosystem.
I started by determining which “screens” I needed, which lined up fairly closely with the API objects. The one difference is adding all the task, rewards, and parent functionality under the Kid screen.
My biggest struggles with RN are state management and flexbox styling. With the limited time I imposed on myself, I didn’t build out a full Context
state system, since I’m still fairly novice to all that… though, in reality, that would be the best way to handle the logged in user and their kid information. So all the state management is occurring on each screen, separately.
From there, I just went screen-by-screen, writing code until I was able to get all the data displaying correctly, and in a somewhat readable fashion.
Step 4: Running the App and API
To make sure everything worked locally, I ran the api locally using a SQlite database, serving through artisan serve
, and running it through ngrok. In Postman, I created some endpoint collections and tested them all out. Then in React Native, I created a base Api component that used axios with two different “base urls”, one for development (ngrok) and one for production. As I spotted problems, I was able to fix them either in the api or RN code, and I could see the results immediately.
For production, I decided on Heroku with a PostgreSQL db. It’s super easy to setup, and their free tier is decent. Once I was satisfied that the api code was good, I deployed to Heroku and changed my RN base url to the heroku url. From there, I went through all the app screens again and made sure everything worked.
Step 5: Publishing
Trying to come up with a name for anything seems to be problematic for many people, and this was no different. After consulting with my kid, we chose ‘Points 4 Kids’ as the app name. So I created a really bad icon and splash screen, and added it to the app.
Using Expo, the build process is a straight-forward (though long) process. Once it was done, I downloaded it, installed it, and ran through everything once more. I could theoretically use this apk on the Google Play store, but I’m not sure this is something I want to release. I’ve already found a couple of error messages that were just supposed to be for debugging, and frankly, I was not at all concerned with the design aesthetics.
For now, my wife and I will use it, and if some friends are interested, I may sent it their way. This whole idea began on Thursday at 5pm, and my final build was completed on Saturday, just before 5pm… so 48 hours to get a functional, full featured api and mobile app.
Step 6: Future Enhancements
If I decide to spend more time on this project, and maybe release it, there are some definite things I’d want to update…
- The first thing I would do is make the UI a lot better. Maybe screenshot everything and hire someone on Fiverr to make it look nicer.
- The React Native code is kind of a jumble, so I would clean that up. First, there are some repeated bits that could be put into their own components. I’d use the Context/Provider hooks for the user and kid state management, instead of re-creating the same state on every screen. Finally, I’d abstract out all the API calls into a separate model/component.
- A better name, and icon/graphics.
- Clean up the API code. Specifically, moving things out of the route closures and into Controllers… and returning Resources, instead of just formatted arrays.
- Unit/Acceptance testing everywhere.