Downloading .ics Files in Mendix Native Apps (Banner Image)
Downloading .ics Files in Mendix Native Apps

Downloading .ics Files in Mendix Native Apps

Published in
7 min readMar 1, 2024

--

In this article, I’ll explain how to use the new Mendix Microflow URLs and the built-in power of phone browsers to open a variety of file types securely and easily, without having to use high-code JavaScript extensions in your Native app. This article will also highlight the excellent client-server possibilities available in Mendix, so let’s jump right into it.

If you have built Native apps in Mendix, you probably know that many of the basic tools you’ve been working with for the web may work somewhat differently.

MJ — “a hyperrealistic depiction of a man downloading a calendar appointment on his phone, make it look like the appointment details (days, times, dates) are jumping out of the screen”
MJ — “a hyperrealistic depiction of a man downloading a calendar appointment on his phone, make it look like the appointment details (days, times, dates) are jumping out of the screen”

For a recent Proof of Concept, we revisited a well-known paradigm: a calendar was needed where users had the option to plan appointments in each other’s calendars, via their Native app. Moreover, they should have the option to download the made appointments (Dutch: Afspraak) as .ics files, so these could then be opened and imported by a native OS calendar application, such as e.g. Google Calendar, MS Outlook or similar. The problem here is that we need to be able to determine what program to open; in other words, we need to determine the user’s preferred calendar app!

In a browser this is easy; browsers are specialized utilities for opening a variety of content, including e.g. .html, .docx, .xml, and .ics, for example. Knowing what to do with these files, e.g. displaying inside the browser, or deep linking to an OS app specialized for this file type, is what browsers do best.

Now imagine we’re building a React-Native Mendix app, and we want to download and open an .ics file. Downloading is simple in Mendix, but opening will be a challenge. If you want to use a high-code solution, that is a perfectly fine option, until the code breaks down and no high-coders are around to debug or maintain the code. Moreover, in this case, it seems that this solution wasn’t ready yet either.

It led me to wonder that there had to be a safe and secure way to be able to use a browser download.

A 4-Step Solution

Let’s go through our solution in four steps. In principle, this paradigm can be used for any type of downloadable file (System.FileDocument) in which we want to use the browser to open it, using the operating system’s preferred/dedicated app.

  1. In a Nanoflow ACT_Afspraak_Download (see image below), we start with getting the Mendix Server address (so we can test both locally and in the cloud), and we pass that as a variable to an ACT_Afspraak_ProvisionICSAndDownloadLink. This flow returns a link that can be consumed, including two query parameters: IcsID for an ICS object, and a password. If the link is not an empty String, it will be opened with the Open URL activity — more on this later.
Screenshot of the client Nanoflow ACT_Afspraak_Download (triggered from the phone/device), which first gets a DownloadLink and then opens it.
Screenshot of the client Nanoflow ACT_Afspraak_Download (triggered from the phone/device), which first gets a DownloadLink and then opens it.

2. In the Microflow ACT_Afspraak_ProvisionICSAndDownloadLink (see below), we first do a retrieve of the $Afspraak_OwnedByUser, using an XPath that checks if the User is entitled to the $Afspraak’ in question. If an Afspraak is found, we generate a random single-use $Password, and in the next three activities create an ICS file. Finally, we generate a $DownloadLink, and make sure that this link is permanently set on the $NewICS. This flow will only return a working link to a User with access to this Afspraak.

Screenshot of Microflow ACT_Afspraak_ProvisionICSAndDownloadLink, which returns a the downloadlink if the User is allowed to access the Afspraak.
Screenshot of Microflow ACT_Afspraak_ProvisionICSAndDownloadLink, which returns a the downloadlink if the User is allowed to access the Afspraak.

1 continued: after the Microflow is completed, we are back in the Nanoflow of step 1. We have received a link and check that it is filled. If so, we use an Open URL activity with the $downloadlink. This will trigger the client (phone or device) to use the operating system’s standard browser to open the $DownloadLink. This (deep) link leads to a Microflow (step 3) that has been exposed, which also means that we will have to either log in, or provision an anonymous $User +$ Session. We chose the latter to allow for a seamless user experience, plus we made sure that an ICS file could only be downloaded once, by deleting it immediately after password-guarded consumption. Moreover, any ICS older than 10 minutes is automatically deleted by a scheduled event.

Using the brand-new Mendix function called Microflow URLs, we can expose any Microflow and its input parameters. In the past, this would have involved configuring the DeepLink module, but no more!

Screenshot of DL_ICS_DownloadAndDelete_Anon, which is exposed via a URL and contains two parameters, IcsID and R (password)
Screenshot of DL_ICS_DownloadAndDelete_Anon, which is exposed via a URL and contains two parameters, IcsID and R (password)

3. In this DL_ICS_DownloadAndDelete_Anon Microflow, we first retrieve the ICS using the $IcsID and the password. The name $R was chosen to make the function of the parameter oblique, meaning more secure. If the $ICS was found, we would show a ClosePage_Anon, download the ICS, Log the download, and trigger an asynchronous deletion of the ICS file.

Since a Microflow runs in one transaction, both downloading and deleting an ICS in 1 transaction will lead to errors, as the file will have already been deleted before the download is started. We wanted to make the system as robust as possible, so we used the Java Action CommunityCommons.executeMicroflowInBackground to trigger a Delete, just after the download was completed.

4. Indeed, in the final Microflow SUB_ICS_Clean, after a short delay, we deleted the ICS.

Screenshot of SUB_ICS_Clean, which is triggered asynchronously via CommunityCommons.executeMicroflowInBackground
Screenshot of SUB_ICS_Clean, which is triggered asynchronously via CommunityCommons.executeMicroflowInBackground

How secure is this?

Very! However, if we want to make this method even safer, we could add an XPath constraint in the retrieve of step 3, that checks that the $Ics/createdDate is less than ten minutes old. We could also random hash the $Ics/_ID; this is currently an auto number, which was chosen because this was a POC. Mendix uses a string version of java.util.UUID() to create these hashes. No hacker will be able to successfully guess and try a cross-combination of a random hash ID * a random hash single-use password within 10 minutes of file creation. Moreover, since Mendix uses HTTPS/TLS, the transmission of the download link is encrypted, and due to the immediate consumption of the link, the file will be scrubbed automatically and immediately anyway (step 4).

The Proof is in the Demo Pudding

So, you might wonder what all of this looks like in the actual app? Here is a .gif file of the entire process from within a BlueStracks client. It really is seamless.

Gif showing the download in a BlueStacks client, forwarding to Chrome and Google Calendar
Gif showing the download in a BlueStacks client, forwarding to Chrome and Google Calendar

To show that everything is working as described above, here is the same download flow with breakpoints added in Mendix.

Gif showing the same steps with breakpoints in Mendix
GIF showing the same steps with breakpoints in Mendix

To round it off, here is a communication diagram that outlines what we built by smartly employing both Nanoflows, Microflows with URLs, and asynchronously triggered Microflows. Mark that the light-yellow box signifies a series of apps on the client device (phone), and the blue box is the internet, which contains the Mendix Server.

Communication Diagram outlining the process for downloading an ICS file, created using https://sequencediagram.org/

Concluding, Mendix has some very cool and handy out-of-the-box tools including Nanoflows, Microflows, Microflow URLs, CommunityCommons.executeMicroflowInBackground, and CommunityCommons.RandomHash and built-in HTTPS/TLS. These tools allow you to construct rather elaborate and secure client-server communication processes, such as the one described above. Likewise, it is possible to securely download files and have a browser perform complicated redirection work for you, without having to write a lot of code.

For me, that’s the power of Low Code!

Do you want to make your Mendix apps even more efficient? Check out my other articles below ;-)

#About: Wouter Penris
Wouter is a (lead) Mendix Software Engineer (Expert/MVP/Trainer) with a background in education (English & Music) and in music (Jazz Vocals & piano); a multi-potentialite. Where as a teacher he spent years perfecting the art of instructing his students as simply and understandably as possible, he now immensely enjoys using this same skill to build high-tech products with an intuitive and easily-understandably UX. He is a highly creative problem solver, in which he blends research, technology and aesthetics into actual business value and advice. Wouter is a communicator at heart and especially enjoys working with international clients due to his background in English. Wouter currently works as Senior Principal Expert in Mendix at Ordina.

Ordina promo, January 2024 — www.ordina.nl

From the Publisher -

Inspired by this article to bring your ideas to life with Mendix? Sign up for a free account! You’ll get instant access to the Mendix Academy, where you can start building your skills.

For more articles like this one, visit our Medium page. And you can find a wealth of instructional videos on our community YouTube page.

Speaking of our community, join us in our Slack community channel. We’d love to hear your ideas and insights!

--

--