React-native-background-geolocation: Auto-sync without HTTP Interaction (Firebase Database)

Created on 18 Jan 2018  路  9Comments  路  Source: transistorsoft/react-native-background-geolocation

Your Environment

  • Plugin version: 2.10.1
  • Platform: iOS or Android
  • OS version: Ubuntu 16.04
  • Device manufacturer / model: GM5 and Emulator
  • React Native version (react-native -v): 0.49.5
  • Plugin config ---->
    foregroundService: true,
    notificationTitle: 'Title',
    notificationColor: '#f3f3f3',
    notificationText: 'Some notification text.',
    notificationPriority: BackgroundGeolocation.NOTIFICATION_PRIORITY_MAX,
    desiredAccuracy: 10,
    distanceFilter: 20,
    elasticityMultiplier: 3,
    stopOnTerminate: false,
    startOnBoot: true,
    forceReloadOnSchedule: true,
    forceReloadOnBoot: true,
    batchSync: true,
    autoSync: true,
    autoSyncThreshold: 20,
    url: 'http://...',
    debug: true,
    logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
    headers : { Authorization: 'Bearer .....' },

Context

We are using Firebase database on our application. As you may know, the Firebase Realtime Database is a cloud-hosted NoSQL database that lets you store and sync data between your users in realtime. It has offline-support. In practice, you call firebase methods to persist data to its database, like react-native-background-geolocation plugin Firebase database has its own persistence layer. You save data to the database-copy on the mobile device and Firebase handles data sync when network is available. We have set the distanceFilter, elasticityMultiplier, autoSync and autoSyncThreshold configurations and we have a pretty good optimization on getting location updates from devices.

Expected Behavior

We would like to call Firebase Database SDK functions whenever (now) plugin is configured to execute HTTP calls to sync instead of http calls. We would like to get location updates in batches as the configured distanceFilter, elasticityMultiplier, autoSync and autoSyncThreshold parameters as in HTTP sync'ing.

Most helpful comment

"Headless JS" doesn't make sense for iOS since iOS has no concept of "background services".

When an iOS app is terminated, it too will terminate all your Javascript. However, when an iOS app is rebooted (eg: due to device detected to have exited stationary geofence), iOS will reboot your entire app in the background, including your Javascript.

There will never be a "Headless JS" for iOS.

All 9 comments

Use Firebase REST API and provide that url to the plugin.

I know that option. However that requires the management of Firebase idToken and renewal of it upon expiry on the onHttp.Failure event of the plugin. That's why I would like to bring this option on the table and get your opinion.

Isn't it possible to "override what sync will do" any how? Or get triggered when httpSync would be triggered?

When your app is terminated, your Javascript app, where you're listening to the plugin's events, is terminated. What then? On Android, only the plugin's native Android service remains running.

OK, when our app is terminated will onHttp callbacks work? I'm raising this question since we need to refresh access token, which is set on the header configuration of plugin. And to do this we need to rely on the started Firebase session on the application.

To elaborate, will following work when the app is terminated?

BackgroundGeolocation.onHttp(function(response) {
  // Success
}, function(response) {
  if(401 === response.status) {
     firebase.auth.currentUser.getIdToken(true).then((token) => {
       const headers = { Authorization: `Bearer ${token}` };
       // Set (override) react-native-background-geolocation header configuration here 
       // Call react-native-background-geolocation sync method
    });
  }
});

No. All Javascript is terminated.

Btw, don't use #onHttp, use on('http'). Always use #on to listen to events.

You should try using the plugin's "Headless JS" feature.

This allows you to provide a Javascript callback when your app is terminated.

let HeadlessTask = async (event) => {
  console.log('[js] BackgroundGeolocation HeadlessTask: ', event);
  switch(event.name) {
    case 'http':
      // Handle 401 here.
      let params = event.params;
      let status = params.status;
      if (status === 401) {

      }
      break;
  }
}
AppRegistry.registerHeadlessTask('BackgroundGeolocation', () => HeadlessTask);

Thank you for your consultation. However, it seems that this is an Android-only solution. For IOS, what do you advise to do?

"Headless JS" doesn't make sense for iOS since iOS has no concept of "background services".

When an iOS app is terminated, it too will terminate all your Javascript. However, when an iOS app is rebooted (eg: due to device detected to have exited stationary geofence), iOS will reboot your entire app in the background, including your Javascript.

There will never be a "Headless JS" for iOS.

That totally makes sense. Thank you very much!

Was this page helpful?
0 / 5 - 0 ratings