Simon Eckerstorfer

Proximity Unlocked: Building Smart Location-Based Matching Apps in Flutter

Transcript

Simon

Before my talk starts, just out of interest, a quick question. How many of you guys have worked with background location already? Could you raise your hands? It's actually pretty hard to see you. I guess it's a third. I hope there's something new for everyone in my talk. Hi, I'm Simon, but you can also call me the mustache man from Flutter Vienna. In my lightning talk, I will quickly guide you through the things I wish I knew before working with background location. With a lot to cover and not much time, so let's dive right in. The most important technical decision in any geolocation-based project is: How do I get the user's location consistently and efficiently? Technically, there's lots and lots of pitfalls and things to consider. I listed them on this slide. You can trust me, I use different approaches and bump my head into all of those problems. I will save you some time and just tell you where I settled. I use Flutter Background Geolocation. It's a plugin. To be upfront, it's not completely free. For Android release builds, you need a license that costs €360. iOS is completely free. At first, €360 might seem a lot. But you have to consider the time you save by not implementing, testing and debugging all of those problems. If you're building a production application, I argue that outsourcing those headaches to a plugin is the best approach. Flutter Background Geolocation comes with a built-in offline support with SQLite database on your phone, with an HTTP service to sync your data automatically with your backend, and with a motion detection algorithm to only track the user's location when they actually move. It's based on native SDKs for iOS and Android, which have been battle tested for 11 years. You won't find anything comparable to the feature set and the maintenance of this plugin in our ecosystem. It also has great documentation and lots and lots of other features, so I really recommend you to check it out. Now that we have the technical part settled, let's go back to our initial question: How do I get the user's location consistently and efficiently? Let's focus on those two words for a second: consistently and efficiently. When using background location in Flutter, there's always a fine line between data frequency and accuracy and battery life on the other side. You need to realize that putting more weight on one side of the scale always impacts the other side. There is no right or wrong solution here. It is your job to figure out where the balance lies for your specific application needs. However, there are some pointers I can give you, and I added them to this slide. What they all boil down to is one central question. The question is what is the minimal amount of data I truly need to deliver the core value of my application? Everything more will needlessly drain the battery of your users. Apart from that, my top suggestion is to try to minimize HTTP requests in particular because they drain the battery way more than just getting the GPS data. So what are the takeaways? One choose a battle tested plugin to outsource all the headaches. And two only track as little as possible to minimize battery usage. As a very quick side note, there's also a completely different approach to geolocation in general. So-called Bluetooth low energy beacons can be positioned, physically, at points of interest. When the Bluetooth signal is detected by your app, you know where the user is located. This can be useful for navigation in areas with weak GPS signal or for example in malls with multiple floors. Keep this option in the back of your head. Bluetooth Low Energy beacons only serve a very narrow use case, but they can come in handy when used appropriately. Now that we have figured out how to gather the data, we also need to persist it. While the first instinct might be to save the latitude and longitude values directly into your database, I strongly suggest you to use native geospatial data types for your database of choice. We're using Postgres, which comes with an extension called PostGIS. It provides specialized data types for geospatial data like points, planes, areas. And it also comes with support for indexing those columns and functions, SQL functions, for stuff like distance or intersections. I will now show you how efficient queries can be by using PostGIS. Let's imagine we have an app with 10 million users. It's an amazing application. Our goal is to take one specific location, let's say it's a location from a user called Franz. We want to find the 100 closest users to Franz, calculate the distance to Franz in meters exactly and order them accordingly. How long do you think this will take with PostGIS? Give me some guesses. Two years, a bit less. Some other guesses. 20 seconds. Closer. This request, and keep in mind it's 10 million rows in your table, it's one gigabyte of data. And the thing I just explained takes exactly 1.7 seconds. This is amazing. Because if you think about how long this would take if you calculated in your backend, where you first need to gather all the data, it's way longer. And it might even crash your backend with a gigabyte of data. Also, you can see the SQL and the functions. They're super convenient and you don't have to code everything yourself. So the takeaway here is use geospatial data types, indices and functions wherever possible. They have a huge performance improvement on your application and they will future-proof your app. Because we don't want to drive around with our laptop while debugging all the time, we need to set up location mocking. This means that we're able to set the specific location we want or go through a route with a specified speed. For Android, I suggest the application "Lockito". For iOS, Xcode provides some functionality out of the box. But let's be honest, who wants to work with Xcode, right? I suggest to use the application RocketSim. It's a powerful extension to the iOS simulator. And while it has a paid tier, all location features are for free. It integrates seamlessly into your workflow as you see on the screenshot because it's always just on the right of your simulator. So take away: Create a comfortable location mocking setup on both platforms. It will pay its dividends while debugging. However, only mocking the location is not enough. There are just certain situations you will never be able to reproduce inside. You will never realize how your app behaves in subways, how it recovers from unexpected errors or what impact it has on the user's battery. But your users will experience all of those things. So, get yourself a group of testers and deliver regular, small prototypes to validate the behavior. It's a nice break from our screen time and let's be honest, touching some grass wouldn't hurt any of us. The last hurdle to publish any application, as we all painfully are aware of, are the stores. There are great resources that cover the whole process of publishing background location applications. I will just leave you with the most important note: The stores will ask for a good reason to use background location. And the stores will reject you if they deem it not good enough. So, make sure background location is a core feature for your application, because using it for analytics or for gimmicky features will get you rejected. As my time is running out, let's wrap up and think about what we've learned today. Choose a battle-tested plugin to outsource all the pitfalls and headaches. Only track as little background location data as possible to minimize the battery impact. Bluetooth low energy beacons are another approach to geolocation and they can come in useful in very specific use cases. Always try to use database integrations for geospatial data types, indices and functions. They have a huge performance improvement. Create a comfortable location mocking setup on both platforms, but also test in real-world scenarios. And lastly, make sure that background location is a core feature of your application for store compliance. Thank you for your attention and see you at the afterparty.

Vadym

Thank you for your talk. Quite a few questions and I want to ask you first. Would you recommend starting with tracking too much and slimming down or the other way around?

Simon

So what we have did is tracking too much and slimming it down and I recommend the other approach. Because usually you need way, way less geolocation data for your application than you initially think. For us, it was a super cool experience to be able to track every meter of the user and see it pop up on the map. But after a while, we realized that every 100 meters is totally enough for our use case. But obviously, this is different for everyone.

Vadym

Yeah, accepted. Please upload questions. Please be more proactive people. How do you manage to work hand in hand with background location and geofencing?

Simon

I did never use geofencing myself, but it is a feature that is provided by the plugin I mentioned as well. It has geofencing support, but we never used it.

Vadym

Accepted. I believe it's honest, so who am I not to accept it? And the last one I will ask some people. People are upvoting it. Should Postgres, I guess, request be local in my app or in server-side? So local or server-side?

Simon

I would put it server-side. Having this layer between is very helpful for us. And I think those queries are something that belongs more into the backend.

Vadym

Yeah, I mean, like all the pretty huge queries and overall queries are more or less on the backend. And just remember, applications are simple and stupid UIs in most cases. Not in all cases. Thank you very much. All other questions, you can ask him directly afterwards. So during the lunch break. Please do so. Thank you very much. Thank you.

Edit on GitHub