react-native-background-geolocation icon indicating copy to clipboard operation
react-native-background-geolocation copied to clipboard

Realtime Database Firebase

Open renangc90 opened this issue 7 months ago • 13 comments

I replaced sqlite with firebase, but it doesn't work with the app in the background

Your Environment

  • Plugin version: 4.16.3
  • Platform: Android
  • OS version: 13
  • Device manufacturer / model: Samsung A54
  • React Native version (react-native -v): 2.0.1
  • Plugin config

import React from 'react';
import { Switch, Text, View, PermissionsAndroid, Platform } from 'react-native';
import { dbFirebase } from '../../services/firebaseConfig';
import { set, ref } from 'firebase/database';

import BackgroundGeolocation from "react-native-background-geolocation";

const HelloWorld = () => {
  const [enabled, setEnabled] = React.useState(false);
  const [location, setLocation] = React.useState('');

  const sanitizeFirebaseKey = (key) => {
    return key.replace(/[\.\#\$\[\]]/g, '_');
  };

  React.useEffect(() => {
    const requestPermissions = async () => {
      if (Platform.OS === 'android') {
        try {
          const granted = await PermissionsAndroid.requestMultiple([
            PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
            PermissionsAndroid.PERMISSIONS.ACCESS_BACKGROUND_LOCATION,
          ]);
          if (
            granted[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] !== PermissionsAndroid.RESULTS.GRANTED ||
            granted[PermissionsAndroid.PERMISSIONS.ACCESS_BACKGROUND_LOCATION] !== PermissionsAndroid.RESULTS.GRANTED
          ) {
            console.error("Permissions not granted");
            return;
          }
        } catch (err) {
          console.warn(err);
        }
      }
    };

    requestPermissions();

    BackgroundGeolocation.ready({
      desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
      distanceFilter: 5,
      stopTimeout: 1,
      debug: true,
      logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
      stopOnTerminate: false,
      startOnBoot: true,
      foregroundService: true,
      notification: {
        title: "Background tracking",
        text: "Your location is being tracked",
      },
    }).then((state) => {
      setEnabled(state.enabled);
      console.log("- BackgroundGeolocation is configured and ready: ", state.enabled);

      const onLocation = BackgroundGeolocation.onLocation(async (location) => {
        console.log('[onLocation]', location);
        setLocation(JSON.stringify(location, null, 2));

        try {
          const sanitizedTimestamp = sanitizeFirebaseKey(new Date(location.timestamp).toISOString());
          const locationRef = ref(dbFirebase, `locations/${location.uuid}_${sanitizedTimestamp}`);
          await set(locationRef, {
            latitude: location.coords.latitude,
            longitude: location.coords.longitude,
            timestamp: location.timestamp
          });
          console.log("Location saved to Firebase");
        } catch (error) {
          console.error("Error saving location to Firebase: ", error);
        }
      });

      const onMotionChange = BackgroundGeolocation.onMotionChange((event) => {
        console.log('[onMotionChange]', event);
      });

      const onActivityChange = BackgroundGeolocation.onActivityChange((event) => {
        console.log('[onActivityChange]', event);
      });

      const onProviderChange = BackgroundGeolocation.onProviderChange((event) => {
        console.log('[onProviderChange]', event);
      });

      return () => {
        onLocation.remove();
        onMotionChange.remove();
        onActivityChange.remove();
        onProviderChange.remove();
      };
    }).catch(error => {
      console.error("Error during BackgroundGeolocation ready: ", error);
    });

  }, []);

  React.useEffect(() => {
    if (enabled) {
      BackgroundGeolocation.start().then(() => {
        console.log("BackgroundGeolocation started");
      }).catch(error => {
        if (error.message === "Waiting for previous start action to complete") {
          BackgroundGeolocation.stop().then(() => {
            console.log("BackgroundGeolocation stopped, restarting...");
            BackgroundGeolocation.start().then(() => {
              console.log("BackgroundGeolocation restarted");
            }).catch(error => {
              console.error("Error restarting BackgroundGeolocation: ", error);
            });
          }).catch(stopError => {
            console.error("Error stopping BackgroundGeolocation: ", stopError);
          });
        } else {
          console.error("Error starting BackgroundGeolocation: ", error);
        }
      });
    } else {
      BackgroundGeolocation.stop().then(() => {
        console.log("BackgroundGeolocation stopped");
      }).catch(error => {
        console.error("Error stopping BackgroundGeolocation: ", error);
      });
      setLocation('');
    }
  }, [enabled]);

  return (
    <View style={{ alignItems: 'center' }}>
      <Text>Click to enable BackgroundGeolocation</Text>
      <Switch value={enabled} onValueChange={setEnabled} />
      <Text style={{ fontFamily: 'monospace', fontSize: 12 }}>{location}</Text>
    </View>
  );
};

export default HelloWorld;

Expected Behavior

My app has the business rule of seeing online service providers in real time on a map. I would like this data to be sent even with the app in the background, so that I don't have to keep the map screen open

Actual Behavior

Only saves when it is in the foreground

Steps to Reproduce

Context

My app has the business rule of seeing online service providers in real time on a map. I would like this data to be sent even with the app in the background, so that I don't have to keep the map screen open

Debug logs

Logs

renangc90 avatar Jun 27 '24 12:06 renangc90