Skip to main content

MyReactNativeApp

The app is as typical a mobile app one could think of. The main feature is to show a customizable product catalog for a set of small business customers. From that catalog, they can filter out and order products for delivery. In other words, it is an online shop.

The mobile app is made with React native with both IOS and Android releases. There is no native code specific to the app besides some third-party libraries which are used. The key libraries that are used in addition to react-native ones are firebase-react-native, redux and react-native-elements. Yet again, nothing special here.

The first versions were developed and distributed via Expo. I found it very well suited for the first phases of development, running and debugging were straightforward. The customer did agree since trying out new versions was convenient especially for IOS users because alpha version distribution for that particular ecosystem is tedious, to say the least

While developing the application I stumbled upon some key findings which I believe also other devs have run into. First of all, as stated in the official development guides, React native (and plain React as well) itself is subject to a constant improvement. This is both good and a bad thing. The benefit is of course that the core libraries will provide more ready made stuff and the development experience will not feel limited compared to native development. Of course, as there are more new features introduced there are more bugs (and an RN developer will run into several bugs) but it also means that at least the more severe ones are fixed promptly and the active community provides workaround when possible. One example of that is the issue with a list inside a scrollable view which is misbehaving but there is an elegant workaround.

To begin with, I was not sure whether React native was a good tech choice. I started the app development almost a year ago (as of writing this post) and I had not followed the general trends of mobile app development for years. Sure, I had heard of RN and I knew it was indeed a popular tech choice already at the time but during my evaluation, I ran to some blog posts warning about the RN pitfalls. What convinced me that RN would be a sound choice was the application domain and initial features. There was nothing special, the app was going to be pretty much straight out from "how to make a simple app" tutorial. Disclaimer: Flutter was not that "in" yet.

As I was quite new to React development, it naturally took many refactoring rounds to "perfect" the app. In the first versions, all the business logic was very much intertwined with the UI code. This made testing harder since I really did not want to write complicated tests and of course testing the business logic with UI tests is an anti-pattern. After introducing redux, tearing out the business logic from the UI became a lot easier and one of the killer features of redux/flux pattern is the testability since there is no need to add any test utilities.

The backend choice was something I did not think about that much in the beginning. Firebase was almost too obvious a choice for this. I wanted to focus on the app development and it took several versions until the app even had a backend. When I took firebase into use, for a long time I just used it without authentication and just used public access to the database since there was no need to put any sensitive data to it. There is also a second backend written in Elixir which I host myself handling the orders.

Besides the database, phone authentication, crash reporting, and logging events are among the list of the features in use. When a user opens the app, it checks if the user is authenticated and if not, it forces the user to go through a text message authentication. This creates a new user to firebase with some app-specific details added. Very much your user authentication 101. If there is a crash during the login, or in any other functionality for that matter, Firebase Crashlytics will notify me with a stacktrace and some device details. I have added a couple of events for example to the order process which is rendered as a graphical illustration illustrating key metrics which are interesting for the customer.

Lastly, I wanted to make the app GDPR compliant from the get-go. This means in essence that no unnecessary user data is stored, the reasons why the data is gathered and to what purpose the data is used is explicity told to the user. The individuals accessing the data need to be logged and the user has the right to wipe out all the data if he/she wants to. In practice, this means that I store only the user's name and some basic company details to Firebase. Order history is stored on the phone and the actual orders are stored only to the customer's emails. All of this is told in brief terms of service shown when the user logs in for the first time. A further development item is to monitor which users are active so that inactive user accounts can be deleted.

I will write some more technical details in some following post.


Comments

Popular posts from this blog

I'm not a passionate developer

A family friend of mine is an airlane pilot. A dream job for most, right? As a child, I certainly thought so. Now that I can have grown-up talks with him, I have discovered a more accurate description of his profession. He says that the truth about the job is that it is boring. To me, that is not that surprising. Airplanes are cool and all, but when you are in the middle of the Atlantic sitting next to the colleague you have been talking to past five years, how stimulating can that be? When he says the job is boring, it is not a bad kind of boring. It is a very specific boring. The "boring" you would want as a passenger. Uneventful.  Yet, he loves his job. According to him, an experienced pilot is most pleased when each and every tiny thing in the flight plan - goes according to plan. Passengers in the cabin of an expert pilot sit in the comfort of not even noticing who is flying. As someone employed in a field where being boring is not exactly in high demand, this sounds pro

Extracting object properties from an IFC file with IfcOpenShell

Besides the object geometry information, IFC files may contain properties for the IFC objects. The properties can be, for example, some predefined dimension information such as an object volume or a choice of material. Some of the properties are predefined in the IFC standards, but custom ones can be added. IFC files can be massive and resource-intensive to process, so in some cases, it helps to separate the object properties from the geometry data. IfcOpenShell  is a toolset for processing IFC files. It is written mostly in C++ but also provides a Python interface. To read an IFC file >>> ifc_file = ifcopenshell.open("model.ifc") Fetch all objects of type IfcSlab >>> slab = ifc_file.by_type("IfcSlab")[1] Get the list of properties >>> slab.IsDefinedBy (#145075=IfcRelDefinesByType('2_fok0__fAcBZmMlQcYwie',#1,$,$,(#27,#59),#145074), #145140=IfcRelDefinesByProperties('3U2LyORgXC2f_hWf6I16C1',#1,$,$,(#27,#59),#145141), #145142

Hubristic developer

Almost half of any Finnish generation goes through a shared experience: the conscript army. An integral part of that experience is learning military slang, a set way people in the army talk. The stories told with said jargon often spread outside of the barracks. It is not uncommon to hear strangers bonding together over beers reminiscing and feeling nostalgic about freezing cold nights spent in tents. There is a similar phenomenon detectable among us coders. To be part of the coder tribe, there is at least one type of story that one must master. That is - of course - ranting about legacy codebases. "Can you believe how much of a mess the previous coders left? Hear, hear!" There is no better way to onboard a new team member than to blame some previous B-team for all the murky parts of the system at hand. This can be seen as harmless, a subject for a good  meme . Rarely do we hold real grudges against "the legacy folk" and can be the best of friends in a social gather