Location Sharing

Location sharing allows users to send a static position or share their real-time location with other participants in a channel. Stream Chat supports both static and live location sharing.

There are two types of location sharing:

  • Static Location: A one-time location share that does not update over time.
  • Live Location: A real-time location sharing that updates over time.

The SDK handles location message creation and updates, but location tracking must be implemented by the application using device location services.

Enabling location sharing

The location sharing feature must be activated at the channel level before it can be used. You have two configuration options: activate it for a single channel using configuration overrides, or enable it globally for all channels of a particular type via channel type settings.

// Enabling it for a channel type
await chat.UpdateChannelTypeAsync("messaging", new UpdateChannelTypeRequest
{
    SharedLocations = true,
});

Sending static location

Static location sharing allows you to send a message containing a static location.

// Create a shared location for the initial message
var location = new SharedLocation
{
    Longitude = longitude,
    Latitude = latitude,
    EndAt = null, // null for static location
    CreatedByDeviceID = "test-device",
};

// Send a message with shared location
await chat.SendMessageAsync("channel-type", "channel-id", new SendMessageRequest
{
    Message = new MessageRequest
    {
        Text = "Test message for shared location",
        SharedLocation = location,
    },
});

Starting live location sharing

Live location sharing enables real-time location updates for a specified duration. The SDK manages the location message lifecycle, but your application is responsible for providing location updates.

// Create a shared location for live location sharing (with EndAt)
var location = new SharedLocation
{
    Longitude = longitude,
    Latitude = latitude,
    EndAt = DateTime.UtcNow.AddHours(1), // Set duration for live location
    CreatedByDeviceID = "test-device",
};

// Send a message with shared location
await chat.SendMessageAsync("channel-type", "channel-id", new SendMessageRequest
{
    Message = new MessageRequest
    {
        Text = "Test message for live location sharing",
        SharedLocation = location,
    },
});

Stopping live location sharing

You can stop live location sharing for a specific message using the message controller:

// Stop live location sharing by setting EndAt to now
await client.UpdateLiveLocationAsync(new UpdateLiveLocationRequest
{
    MessageID = liveLocationMessageId, // The ID of the live location message
    Longitude = longitude,
    Latitude = latitude,
    EndAt = DateTime.UtcNow, // Set EndAt to now to stop sharing
});

Updating live location

Your application must implement location tracking and provide updates to the SDK. The SDK handles updating all the current user's active live location messages and provides a throttling mechanism to prevent excessive API calls.

// Get all active live locations for the current user
var activeLocations = await client.GetUserLiveLocationsAsync(userID);

// Update all active live locations for the user
foreach (var location in activeLocations.ActiveLiveLocations)
{
    await client.UpdateLiveLocationAsync(new UpdateLiveLocationRequest
    {
        MessageID = location.MessageID,
        Longitude = newLongitude, // updated longitude
        Latitude = newLatitude,   // updated latitude
        EndAt = endAt,            // keep the same end time
    });
}

Whenever the location is updated, the message will automatically be updated with the new location.

The SDK will also notify your application when it should start or stop location tracking as well as when the active live location messages change.

// reporter function necessary for LiveLocationManager
const watchLocation = (handler) => {
  const timer = setInterval(() => {
    // retrieval of current location is a app-specific logic
    getCurrentPosition((position) => {
      handler({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
      });
    });
  }, 5000);

  return () => {
    clearInterval(timer);
  };
};

// the manager takes care of registering/ unregistering and reporting location updates
const manager = new LiveLocationManager({
  client,
  getDeviceId, // function should generate a unique device id
  watchLocation, // function should retrieve the location and pass it to the handler function
});

// to start watching and reporting the manager subscriptions have to be initiated
manager.init();

// to stop watching and reporting the manager subscriptions have cleaned up
manager.unregisterSubscriptions();

Events

Whenever a location is created or updated, the following WebSocket events will be sent:

  • message.new: When a new location message is created.
  • message.updated: When a location message is updated.

In Dart, these events are resolved to more specific location events:

  • location.shared: When a new location message is created.
  • location.updated: When a location message is updated.

You can easily check if a message is a location message by checking the message.sharedLocation property. For example, you can use this events to render the locations in a map view.

chatClient.subscribeFor(NewMessageEvent::class, MessageUpdatedEvent::class) { event ->
    // Check if the event is for the watching channel.
    if ((event as? CidEvent)?.cid == "my-watching-cid") {
        when (event) {
            is NewMessageEvent -> event.message.sharedLocation?.let { location ->
                // Add a new location to the map.
            }
            is MessageUpdatedEvent -> event.message.sharedLocation?.let { location ->
                // Update the existing location in the map.
            }
            else -> Unit
        }
    }
}