Mobile app consulting
Mobiilivihko / Nature notebook
- User can enter observations either using web UI https://laji.fi/vihko/home or the Mobile app
- Observations done using Mobile app can be edited (corrected, refined, supplemented) using the web UI
- They can't be edited on Mobiilivihko after submitting, only before submitting
- Observations done using web UI can't be edited in Mobiilivihko
- Introduction and how to use it (only in Finnish): https://laji.fi/about/4981
- Google Play market page: https://play.google.com/store/apps/details?id=org.luomus.mobi
- Code is open source (MIT license), Git: https://github.com/luomus/mobile-vihko-app
- The app uses React Native framework, and Expo is used for building/publishing
- Pure front-end app that uses APIs (laji-api, bird-atlas), consultation is only for the app, not the APIs
- Jest and react-native-testing-library are used for testing, but tests are lacking
- Mobiilivihko has about 800 users
Backend overview
- API
- https://api.laji.fi | https://apitest.laji.fi
- https://laji.fi/about/806
- access_token
- /document
- "Lajistore"
- JSON document storage database - Oracle
- ElasticSearch for searches
- Data model
- https://schema.laji.fi/
- "Lajistore"
- /form
- Field trip - http://tun.fi/JX.519
- Mushroom atlas
- Bird atlas
- Flying-squirrel
- more to come
- /image (/audio)
- /taxon-search / autocomplete / person autocomplete
- personToken -parameter
- Use of URI identifiers
- Triplestore
- Atlas-API https://atlas-api.rahtiapp.fi
- /taxon
- /grid
- Authentication scheme
- https://laji.fi/about/1328
- localhost dev login
Consultant accounts for laji-auth and Pivotal
All consultants need Laji-accounts, both for dev and prod, to use Luomus' services and apps properly.
- Sign up for dev: https://dev.laji.fi/
- Sign up for prod: https://laji.fi/
- When logging into Mobiilivihko, use the dev account, if using the app on localhost, and use prod when using the app from the Play/App Store
- If consultants want to use our backlog, each consultant has to sign up to Pivotal Tracker (https://www.pivotaltracker.com/) and then we can add them to the project
Setting up local development environment
Instructions on GitHub: https://github.com/luomus/mobile-vihko-app
Secrets (will be sent via secret email):
- Access token (ACCESS_TOKEN)
- Url to API dev/prod (API_URL)
- KE-system id (SOURCE_ID)
- Google Maps Geocoding API Key (GEOCODING_API_KEY)
- Google Maps API Key (to app.json)
Using the app on phone so it connects to test API
- Add the .env to root as stated on GitHub, it contains the required access tokens, etc. to connect to API. Ask a developer to send the .env via secret email.
Goals
Evaluation of used tools and their viability to do single codebase cross-platform development for mobile devices (Android, iOS)
Evaluation of the deployment process and developing it to be practical and to follow best practices (Android, iOS)
Evaluation of UI scalability for different screen sizes and adjusting components for different operating systems, and making improvement ideas on these
- Consultant must investigate and fix some of these as an example
Evaluation of used testing tools and guidance on best testing practices
- Consultant must write few tests and Luomus’ developers must know how to continue writing them
Evaluation of the app’s behavior in relation to the OS, especially running on the background and the app permissions, and guiding on how to practically fix these
After consultation, Luomus’ developers have sufficient tools and skills to publish the app
Issues
Build process
1: Publishing to App Store
We can’t send .ipa -files to App Store Connect via Expo, because that requires an ASC API Key, which can only be created by the admin and seemingly can’t be shared easily. Currently we are sending the .ipa to ASC via Apple’s Transporter App, which requires us to use Macbook for publishing a new version of the app every time.
This issue has been investigated but the current method of submitting updates via the Transporter App was considered to be the best available option, so no changes were made.
2: Expo’s env-variables for development and production
Only one set of variables can be added to Expo’s web service. This means that Mobiilivihko test releases send the observations to production, which affects scientific data. (Mikko said this is a “nice to have” feature.)
This issue was investigated and we came up with a solution where we have .env and prod.env -files and we push their contents into EAS before each build. So now we can quite easily also make builds that are connected to the dev server.
3: CI
Should we use a CI tool?
We didn't set up a CI service, but instead we configured Husky, which is a tool that automatically runs lint checks and tests before a git commit can be made. We also discussed that GitHub Actions might be added later on if necessary.
Scaling UI components
4: Pixels, percentages vs. Flex
Which units should be used for component sizes? Pixel values cause the components to be too small on tablets and percentages/flex cause them to be too large. There’s also been issues on how to fit content to containers, as pixels and percentages are both used. Button rows that scale with the largest content is one example that is included in the app.
Extended navbar buttons were overflowing on small screens and now this is fixed. Modals are not stretched on large screens anymore.
5: Alignment
Which alignment to use to make the UI look good for all screen sizes: flex-start, stretch, space-between?
This has been investigated, current implementations were better than expected, no major issues found.
6: Adjustments for different operating systems
For example, Picker and Button Shadows work differently on Android and iOS.
Shadows used to have sharp corners on iOS, now they have been fixed to rounded.
Testing
7: Integration tests
We tried to write one react-native-testing-library integration test for creating and sending an observation event, but managing the state of the app became difficult, and it is hard to write an integration test without starting the app again. We would need some help on how to write integration tests correctly.
Three comprehensive integration test files have been written during the consultation. They include the correct method of initializing the application when starting on a different screen than login. They also include the correct ways of referring to elements.
8: Unit testing of components
Do we need these overall? It would require refactoring all components into a pure component and a container, as stated here: https://fullstackopen.com/en/part10/testing_and_extending_our_application#handling-dependencies-in-tests. We tried this refactoring for HomeComponent tests in Mobiilivihko.
Consultants did not find this kind of testing necessary.
Interaction with the OS
9: GPS tracking on the background
The app might close randomly while running as a background task. This causes GPS tracking to stop and makes the app useless. How to ensure that the app stays on the background, unless closed manually?
This has been investigated for 10+ hours, and location permissions have been modified. If this doesn't improve the tracking, there are no other solutions available, and then we just need to accept this issue. Some phones just are aggressive to kill background apps.
10: Permissions
How to manage app permissions and define what permissions it should require and request?
Permissions have been checked and modified.
Error handling (assigned to Christoffer, Sentry added)
11: Instability on certain phones
App randomly works on some phones and for some phones it crashes, sometimes silently. How to improve catching and logging errors on the app? Also, Mikko reports that the app crashes every 10th time on his Android and then even Android’s error report window crashes when trying to write input.
We purchased Sentry, an error monitoring tool, during the consultation. This has improved the error handling, as it catches also uncaught errors and gathers errors with the same message together, and shows context.
Known usability issues
Invalid documents
- TODO: make sure Sentry catches these 422 and other errors from the API.
If user or the app creates data that is not passed by API validators, submitting the document fails in 422 error, and user cannot save their data. These have come up as surprises like:
- Attached photo is too large (>20 MB).
- User has an outdated version of the app.
- Schema is changed, and we forget to change the app.
There are two solutions for this currently, but these require lot of manual work:
- App submits an error report to our API → we notice it → we can fix things and contact the user.
- User taps the bug-icon on the docyment view → we receive the error → user emails us and we help them (no-one has emailed so far?)
Was not worked on during the consultation, but Sentry should now catch all errors.
Selecting bird atlas square
On the bird atlas form and project, it's important that observations entered to the list view are from a single square (10 x 10 kilometers): the one where the user is making observations on. This why we have implemented a warning system:
- When the atlas form is opened, it shows the square you are on, and asks if this is correct.
- After that, the app shows a warning if you get close to the square border or cross it.
Problem 1: Sometimes the GPS reading from the phone is incorrect, and thus the square shown on step 1 is incorrect, even if the phone claims that the GPS position is accurate. (Accuracy reported by the phone can be <50 meters, even though the coordinates are 1 km away from the true location.)
- TODO: Monitor the location app is getting from GPS long enough, until it does not move too much anymore. But: what is long enough and too much? E.g. for 3 seconds, less than 100 meters of movement between locations?
Problem 2: Some users enter their records after getting home, when they are far away from the square the observations are from. In this case, the user should remember to disable route tracking, because that would place all the observations where they are now, not where they were when making the observations.
- If GPS location != selected square -> disable tracking automatically? Would require reliable GPS location, see problem 1.
- TODO: Mikko will talk with bird atlas coordinators.
Bird Atlas square selection modal now includes a mini-map, and a "locate me" button, to reload location, if the first location is wrong.
Toggling between tracking and not tracking
There are now two options when user starst a new trip:
- Track and draw my route
- Don't track my route
User can then toggle between tracking and not tracking.
Problem 1: It's easy to miss this and have the wrong option selected. How to show more clearly when tracking is on vs. off? Bird atlas is extra sensitive to this, see above.
Problem 2: There's no way to remove a tracked route once you have started it (you can just pause it, not remove existing route). What would be a good way to allow this?
Apart from bird atlas, it's just annoying when you notice 2 hours afterwards that there's no track because you forgot to set tracking on.
- TODO: Think more how to do this. Options:
- When tracking is toggled, show modal explaining what's happening. (e.g. "The app will now start to draw your route on the map. Ok / Cancel")
- Allow user to remove tracked route:
- On the modal
- At the end of the trip (when document is finalized and before it's submitted) allow user to remove route, and/or display a warning if bird atlas square and location are not matching.
Has been done without the consultants.
Inconsistent use of button colors
Current solution is compromise beween two viewpoints: "strong color for the most important button and white for the others" vs. "different color for different actions, e.g. saving is always green and deleting is always red"
- TODO: Make this consistent. Mikko & Robert to think about which way to go.
Requires more discussion, can't be done before that.
Multiple error messages about connection issues
If there's no internet access (airplane mode is on, or some other issue), or if API's are down, the app shows multiple error messages while trying to load data from the API. Show only one error message instead, asking user to check if they have internet access on.
Or better: use login info, forms & maps from cache, so that you can use the app without having good and stabile internet connection.
- TODO: Shown only one error message about connection issue. Make the error message user-friendly. Suppress the rest of the messages.
Done as a byproduct of investigating the slowness of the app: Now some requests have been moved from the start-up to other places, and therefore the number of error messages is more sensible now.
Slowness of the app
Some users (with phones 4+ years old) have said that the app is too slow to use, e.g. opening observation modal takes >10 seconds every time. Is there something that can be done to make it lighter? Low-priority, since most users have reasonably new phones anyway.
Discussed this 2022-12-20: React Native should not cause too much slowness. Maps can be heavy.
- TODO: Check how many map tiles are loaded - can this be controlled / limited?
Has been investigated. App start-up has been made faster, as some requests have been moved elsewhere and the remaining requests are now sent in parallel instead of sequence.
Logging in
Currently when user logs in, they are redirected to a browser to login. This is done because using WebView for authentication via Google (and Facebook?) would require too complicated approval process from them.
Problem 1: When user has logged in in the browser, there is no uniform way to instruct how to get back to he app. Behavior is different in different browsers.
Problem 2: Sometimes after getting back to the app, it suddenly thinks that you are not logged in, and you need to login again. We have not been able to reproduce this consistently. https://www.pivotaltracker.com/story/show/181552843
- TODO: Improve instructions how to get back to the app.
- Close the browser (by swiping up / pressing the close button)
- Swicth to Mobiilivihko via app switcher button
- ...?
Has not been done.