The COVID-19 pandemic has caused many of us to stay isolated and at home, but that's OK! I genuinely enjoy developing software and wanted to take this opportunity to focus on learning. Having some downtime has afforded me to try putting together a system that I otherwise might not have explored building.
In this article, I'll share different aspects about an application I'm building that purposefully put me outside of my comfort zone. In my opinion, having downtime is an opportunity to learn and grow! It's time to take advantage of that.
When the app and system is ready to showcase I'll share more insight into what's actually being built!
The Client Framework
The application being built was intended to run on multiple mobile platforms, so Xamarin was my choice here. I have briefly used Xamarin several years ago, but my reasons for this time through were:
- C#, .NET, and Visual Studio support. There were many things I wanted to learn about, but I wanted to limit myself to a familiar foundation so that I could still feel that I'm making progress.
- Supports iOS and Android right from the start. I thought it would be an interesting software design challenge to be able to build base components in a shared library and then leverage dependency injection for platform-specific components.
- Traction. Xamarin has been around for a number of years now, and it's only continuing to gain support. I didn't want to focus on a platform or SDK that wasn't getting any love.
Xamarin was easy to get setup with because of the familiar pieces, but I was pushed out of my comfort zone to learn about how certain things are handled differently on iOS and Android
I was able to learn about:
- Android/iOS permission requests
- The new UI controls in Xamarin (vs WPF which I'm used to)
- More practice with async/await and UI experience
- Different mobile API frameworks (Crashlytics, Google Analytics, user control libraries)
The Server Framework
I've joked with my colleagues in the past that "web isn't my thing", but what I really mean is that "I don't have experience making web pages". I've build many client server systems in my professional experience and hobby programming, but serving nice-looking web pages hasn't been my strength.
For the system that I'm designing in my downtime, I need an application server. I decided to go with ASP.NET Core because I haven't set up many ASP.NET systems before, and I don't have experience having them hosted in the cloud. However, I do have experience with C# and Visual Studio, so again, this seemed like a good balance of trying new things with some familiar concepts to ensure I could make progress.
In short order, I was able to get a handful of application server routes setup and communicating with the client application properly. The most difficult part was truly just making sure firewall and SSH settings were configured locally, and a handful of times of cursing at my phone for not having it on WiFi (and thus not seeing the development server on my local network)!
I was able to learn about:
- Authentication attributes (and JWT token handling)
- Routes with query parameters
- Serving static content as well as application requests
The Authentication Framework
This one was fun. Having a professional career in software development, one thing that scares everyone away is designing authentication and user management. Nobody wants to because it's complex, has plenty of edge cases, and... it's probably critical to your system working :)
Thankfully, Firebase saved the day. I wrote about this already, but Firebase truly made authentication and user management way more straight forward than I'm used to. The hardest parts of working with Firebase had nothing to do with Firebase and everything to do with implementing OAuth for the providers of my choosing.
Because I could use OAuth to authenticate users and have identifiable information provided via a JWT, having a simple registration and login system that mapped OAuth'd users to some sort of internal-system user identifier was trivial. All of the routes for my web application could also authenticate and control access via this same JWT! One of the scariest components about building a system became a relatively light lift.
I was able to learn about:
- OAuth for popular providers (Google, Facebook, etc...)
- OAuth scopes
- JWT tokens
- Firebase SDK from a server and client side
- Route authentication in ASP.NET using JWTs
The Database Framework
As part of the journey for exploring unfamiliar technology in my downtime, I decided I'd like to pursue a database that wasn't SQL-based. I was already using Firebase for authentication and Google offers an intriguing document store in Firebase that provides real-time update triggers.
Being unused to document databases (I'm much more familiar with relational databases), I spent some time trying to design my schemas that I intended to use. One thing that caught me off guard pretty quickly was that in order to modify to a list of things, I'd need to have a local copy of the list, manipulate the collection, and then push the entire structure back to replace the existing structure. This seemed like overkill what I was trying to do, but the alternative was that I could modify objects in the data store to add/remove child items, but each child item would receive another identifier object as a linking object. So a list of X things actually meant 2X things (one for the identifier, one for the entry). Again, this was overkill.
I decided to go back to familiar technology but explore a not so familiar space! I have a good deal of experience working with SQLite and MySQL from my career. What I don't have a lot of experience with is the management and provision of a MySQL instance with availability in the cloud! Enter Amazon RDS!
Switching to Amazon RDS meant a bit of a learning curve for making sure I could host and configure an instance of MySQL in the cloud. I was able to learn about various Amazon AWS services and roles and how they play together. But once the instance was up and running, I was able to get up and running effectively.
The Tooling
I had help with this one, fortunately, from a friend and old colleague of mine Graeme Harvey. If you've worked with me professionally or on a hobby project, one of the things I admit pretty quickly is that I really dislike tinkering to get a configuration right. Generally this is because there's a lot of tweaking to get something set up right, documentation to understand, and frustrating trial and error.
Source control was going to be git. I didn't even want to consider anything else. Git is so widely used now that I didn't see a real benefit to trying to learn a new source control system. Repository management though? BitBucket. I'm a huge fan of the Atlassian suite of products having used them professionally for many many years.
And with that said Jira for issue management. Again, I've used Jira professionally for many years. What I've never done is had my own Jira instance though! This was made very simple by Atlassian, and not being a company that's generating big bucks I was able to get the free tier that handles all of my needs. Jira is straight up awesome for issue management and visibility into your ongoing work.
Another no-brainer for me was getting Slack setup. Slack is something I've used a lot professionally but like Jira, I've never had my own Slack instance. Simple to setup and works just like I'm used to in my career. This wasn't really a huge requirement but working with another person provided a nice workspace for chatting about stuff we were working on.
And finally... builds. I wrote about using Circle CI to get our server builds up and running already, and to re-iterate it was extremely simple. I even have them wired up to report back to Slack when we push code up to BitBucket! Where we're still having some fun is figuring out how to deploy our application server builds to an EC2 instance automatically. This would allow us to "release" to a branch and have production hosting of our application server get updated in the cloud!
But we're building a mobile application in Xamarin, so we have three outputs:
- The application server in ASP.NET
- The Android client
- The iOS client
Mobile app development gets interesting because what you're actually building is intended to run on a device and not a desktop/server... And why that matters is that generally your desktop or server application will be output as a binary, but your mobile application will be some sort of package you'll need to sign and distribute on an app store.
After some back and forth, we decided to explore App Center. If I'm being honest, this was equally as easy to setup for our iOS and Android apps using Xamarin as our server was to setup using Circle CI for builds. App Center provided a simple wizard for triggering off of our BitBucket repositories getting new commits to a branch, and the rest was done for us.
What I learned:
- Git+BitBucket = Free git repository hosting (private if you want) and plenty of integrations
- Jira = Free issue management and kanban board with plenty of integrations
- Slack = Free chat workspace with plenty of integrations
- CircleCI = Free continuous builds with integrations into ALL the other things I just mentioned :)
- App Center = Free continuous builds for iOS and Android Xamarin apps with plenty of integrations!
In Summary
It's been a couple of weeks of getting to try building out this project and setting up these different systems to go to work for me. I've been able to learn a lot about new or previously unexplored SDKs/technology and even learn some different facets of things I already have professional experience with.
I'm not one to sit idle... So using my downtime to learn cool things and build something has been an awesome time! I'd highly recommend that if you're in quarantine, lockdown, or otherwise unable to really get out and do too much that you try your hand at something new! Get creative. Get learning.
Be safe and stay healthy!