In mid-January I took a week off my day job to have a busman's holiday working on eVitabu (you can read an introduction to eVitabu here). As has become traditional, I travelled to my colleague Geoff's home to spend the week discussing the project, developing the applications, and enjoying plenty of walks.
I had two goals for the week, one from the charity and one set by Google. For privacy reasons, Google requires apps that allow / require registration to also provide the user an option to delete their accounts. I actually missed the first deadline for that, and Google granted an extension to June 2024.
My second goal was to enable announcements added in EVM (the eVitabu management console) to be sent on the users via WhatsApp or push notification. This would increase engagement with the charity's partners, so it's the next most important feature for the charity. Sending the announcement via email would have been easy, but we've noticed that our African users don't use email as much as WhatsApp / Facebook / others.
Spoiler alert: I made good progress on the announcements / messaging piece and barely any progress on the account deletion. Good job I've got that extension 🤣!
I recently started to use a tool called Sonarqube, which performs static analysis on source code to find potential bugs and security vulnerabilities. This is something the teams use at work, so I'm keen to make use of it in my own projects - both to improve the application but also to develop a better understanding of the tool. I've got that working well for EVM (PHP based) but haven't had any success with the Android project as yet.
Whenever I perform a release of EVM (web) and eVitabu (Android app) I aim to have any dependencies updated to fix any bugs and gain any improvements. I'll be ensuring those get updated too.
Android app dependency changes & tooling
While a side goal, this seemed an easy place to start. Android Studio had been warning for some time that Gradle, the tool used to manage builds of the app, needed updating - my project was still using Gradle 4.1.1. I stepped through various versions until reaching 8.2.1 which was the latest at the time.
Other dependencies were updated too, which often causes a bit of a headache as eVitabu is supported on Android Lollipop (5.0 and 5.1) up to Android 14. Looking at the statistics, we've only got 34 registered users using Android Marshmallow (6) and below, so at some point we need to decide if we're going to drop some minimum versions. So far, in limited testing, the dependency updates haven't caused any problems.
WhatsApp messaging / push notifications
While WhatsApp was definitely the ideal, it became clear there was a cost to sending WhatsApp messages. There were a couple of options when it came to APIs, and I researched going directly to WhatsApp or using Twilio. Both (rightly) required users to opt in to receiving messages, so we would need to perform an app update, or send an email, to prompt users in that regard. That presented a challenge.
I've already mentioned how our partners don't tend to worry about email so much - clearly sending an email about consenting to WhatsApp was going to have the same problem as our normal messaging. Presenting a consent request via the eVitabu app was also going to be challenging, as looking at the statistics I can see the oldest known version of the app in use is from July 2019 (version 1.3.5) and there are people running unknown versions (which means an installation prior to when I started to send the version number in the user agent). The vast majority of our users (1,126 of over 1,600) have not updated to the latest version.
Clearly getting people to install updates was going to be a problem. Given that barrier, and the fact that not everyone used WhatsApp, we opted to go down the push notifications route instead. That way, anyone with an updated version of eVitabu would benefit. For users on newer versions of Android, they'd still have to opt in to notifications (a permissions dialog would appear) but we'd know messages would be received at least.
After some research into Firebase Cloud Messaging (FCM) I found things had changed since I wrote an app for my Masters degree that used push notifications. For a start, I'd used Google Cloud Messaging previously, and that was shut down in 2022! I was relived to find that adding FCM support was as easy as including a dependency and adding a background service to the app. The service listens for push notifications and then provides these to the user.
Unwanted "bonus quest"
In order to interact with Google's Firebase platform your application has to be digitally signed. Unfortunately, I'd forgotten the password to the Java keystore that contained the signing key. I managed to retrieve the password, by brute force, and you can read more about how I used Microsoft Copilot to help me do that here.
Handling FCM messages
There are two scenarios for FCM messages - they are either received while the app is in the background (e.g. not running or not on screen), or the message arrives when the user is actively using the app.
For messages received while the app is in the background, Android will automatically put a notification in the notification area (the bar along the top, with the clock) and will show the notification on screen if the screen is on. Tapping on the notification then opens the eVitabu app. If the user is actually in the app at the time nothing happens unless the developer handles this explicitly.
I opted for a notification to appear in both scenarios, prompting the user to tap the notification for more information. On tapping, the user is taken to eVitabu's announcements screen and that's when I hit a problem. In the current configuration, eVitabu opens the
main activity, then signs the user in, downloads XML for the contributors and any announcements, and waits for the user to do whatever they need. When tapping the notification I was bypassing a lot of steps, dropping the user straight to the announcements. If they'd not been signed in, the announcements screen would attempt to download the announcement data and promptly fail❌.
I could take the data from the FCM message to populate the announcements screen, however, I still need to maintain the existing functionality in EVM for users of old versions of the app. While getting the data twice (once by the FCM message, once by XML download) isn't data efficient (very important when you're billed by the megabyte) it was the quickest option for the moment. Plus it means that if an FCM message expires, or fails to be delivered, the user can still see any announcements if they go to that screen by hand.
So, after a bit of a rejig, I arranged for the app to always sign the user in and then divert them to either the announcements screen or the contributors & content search screen as appropriate.
Bonus quest 2
While testing push notifications on Android 5 (very old, and the oldest version eVitabu supports) I noticed that browsing by topic didn't work. This is a secondary content searching method where the user taps a topic of interest (e.g. family, or farming) and eVitabu performs the search automatically. For some reason doing this on Android 5 would crash the app.
I couldn't understand why my FCM changes were causing this, and spent time testing with an older release of the app. I hadn't just broken topic searching - it had never worked on Android 5. Apparently I didn't test that very well.
Fortunately for me, Android Studio was clearly showing me the problem and had been shouting about it via code inspection findings for a while. That problem will be fixed on next release.
Due to the unplanned bonus quests, time taken to update dependencies (necessary), and the research I had to do I only managed to implement FCM handling in the app. That's great, because it means that eVitabu will handle messages that are sent, but not complete as messages can only be sent via the Firebase console at the moment (i.e. by me).
I need to fully test the app following dependency updates and adding FCM support, then I'll be working on building FCM support into EVM next, so the APF team  can post announcements as they normally do but also deliver these by push notification. My plan will be to release an Android app update before EVM is ready, so partners can update ahead of time.
Once push notifications are built in to EVM and the app I'll go back to working on the account deletion piece.
Banner image: eVitabu app banner.
 That's a lot of acronyms, so to recap:
- FCM - Firebase Cloud Messaging
- EVM - eVitabu Management
- APF - African Pastors Fellowship