Skip to content

Instantly share code, notes, and snippets.

@mkruisselbrink
Last active June 24, 2022 06:27
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mkruisselbrink/d0d38b38979a37778e71 to your computer and use it in GitHub Desktop.
Save mkruisselbrink/d0d38b38979a37778e71 to your computer and use it in GitHub Desktop.
Geolocation in service workers

Exposing Geolocation to Service Workers

As I see it there are various situations where having access to geographical location would be useful from a service worker.

  1. Get the current location In particular, to handle some event the service worker might like to know the current location.

  2. Keep track of the location for some time The main thing here is things like fitness trackers, where the web app can start/stop tracking the location, and can access the entire track whenever it needs to, but no realtime updates of the current location are needed in the background.

  3. Get notified when the device enters/leaves some region This is addressed by the Geofencing API.

  4. Regularly share the current location and/or past track with a server Social networks might like to be able to show the current location of their users to their friends, other more specific agricultural use cases have been brought up.

Current location

Some of these use cases are easier to address than others. For the first one, just exposing navigator.geolocation.getCurrentLocation would work (although it might be nicer to have a more modern version of that API like Promise<Position> getCurrentLocation(optional PositionOptions options)). The issue here would be what to do about permissions; one way to deal with that would be to require some webpage to request some kind of background geolocation permission (using the permissions API) before a service worker is able to call getCurrentLocation.

Notification when position changes

As mentioned, use case 3 is already being addressed by the geofencing API. Together with the ability to get the current location this allows both absolute (notify when I'm at this specific location) and relative (notify when I've moved at least X miles) notifications.

Track the user over a longer time period.

So that leaves use case 2 and use case 4. For those use cases I think we'll want some kind of new API. Neither the existing geolocation API, nor the new geofencing API are enough to properly address these use cases.

For use case 2, I think some kind of API that allows you to start/stop tracking the user, as well as access the recorded track would be quite nice to have. In sample code, something like the following:

// start recording a track
navigator.geolocation.startTrack({
    tag: 'some identifier for a track',
    // other options, maybe indicating desired frequency/accuracy of track
  }).then(track => {
    // track is some object representing the track in progress
  }).catch(e => {
    // failed to start tracking
  });
  
// check up on a track that is currently being recorded
navigator.geolocation.getTrack({tag: 'some identifier'})
  .then(track => {
    track.isActive.then(active => console.log('Tracking is active: ' + active));
    track.getLog({/* options */}).then(log => {
        console.log('Logged track so far:');
        log.positions.forEach(position => console.log(position));
        // clear logged positions to free up memory
        log.clear();
      });
  });
  
// stop recording for a particular track
navigator.geolocation.getTrack({tag: 'some id'})
  .then(track => track.stop())
  .then(log => {
      console.log('Logged track:');
      log.positions.forEach(position => console.log(position));
  });
  
// in service worker, get notified when recording of a track stops
self.onGeolocationTrackError = function(e) {
  console.log('Problems in track ' + e.track.tag);
  e.track.getLog().then(log => console.log('Track logged ' + log.length + ' positions'));
};

This isn't a complete API, and would need some way to actually associate the tracks with service workers. Also maybe this could be somehow changed into a new version of the watchPosition API, by allowing the creation of tracks that don't actually record historic locations, and by enabling web pages (but not service workers) to sign up for an onupdate event on the Track instance.

Actively share real time location with a web server

That leaves use case 4. Some parts of it might already be sufficiently addressed with the above described APIs. A website could use push messages to poll a specific service worker/user for its current location, and while a web app is being actively used the web app can push its location to a remote server as well. To actively push the location while the web app is not being used some kind of periodic background sync API (not yet specified) could be used. Either by just getting the current location in the background sync event, or by using something like the tracking API to get accurate location history for the time periods in between sync events.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment