惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy & Cybersecurity Law Blog
SecWiki News
SecWiki News
T
Troy Hunt's Blog
Y
Y Combinator Blog
V
V2EX
美团技术团队
Last Week in AI
Last Week in AI
S
Security @ Cisco Blogs
IT之家
IT之家
博客园_首页
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
阮一峰的网络日志
阮一峰的网络日志
AI
AI
罗磊的独立博客
人人都是产品经理
人人都是产品经理
H
Hacker News: Front Page
N
News and Events Feed by Topic
P
Privacy International News Feed
V2EX - 技术
V2EX - 技术
Recent Commits to openclaw:main
Recent Commits to openclaw:main
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
GbyAI
GbyAI
L
LINUX DO - 热门话题
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Azure Blog
Microsoft Azure Blog
Martin Fowler
Martin Fowler
月光博客
月光博客
WordPress大学
WordPress大学
Latest news
Latest news
Google DeepMind News
Google DeepMind News
S
Schneier on Security
N
Netflix TechBlog - Medium
腾讯CDC
T
Tailwind CSS Blog
TaoSecurity Blog
TaoSecurity Blog
S
Secure Thoughts
L
LINUX DO - 最新话题
Project Zero
Project Zero
Cyberwarzone
Cyberwarzone
D
DataBreaches.Net
Webroot Blog
Webroot Blog
B
Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
H
Help Net Security
L
LangChain Blog
A
Arctic Wolf
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

Supabase Blog

AI Agents Know About Supabase. They Don't Always Use It Right. Custom OIDC Providers for Supabase Auth 100,000 GitHub stars Supabase docs over SSH Navigating Regional Network Blocks Supabase Joins the Stripe Projects Developer Preview Log Drains: Now available on Pro Supabase Storage: major performance, security, and reliability updates Supabase incident on February 12, 2026 Hydra joins Supabase X / Twitter OAuth 2.0 is now available for Supabase Auth BKND joins Supabase Supabase is now an official Claude connector Supabase PrivateLink is now available Introducing: Postgres Best Practices When to use Read Replicas vs. bigger compute Introducing TRAE SOLO integration with Supabase Supabase Security Retro: 2025 Sync Stripe Data to Your Supabase Database in One Click Building ChatGPT Apps with Supabase Edge Functions and mcp-use Own Your Observability: Supabase Metrics API Introducing iceberg-js: A JavaScript Client for Apache Iceberg Introducing Supabase for Platforms Adding Async Streaming to Postgres Foreign Data Wrappers Build "Sign in with Your App" using Supabase Auth Introducing Seven New Email Templates for Supabase Auth The new Supabase power for Kiro Introducing Supabase ETL Introducing Analytics Buckets Introducing Vector Buckets Snap, Inc. Launches Snap Cloud, Powered by Supabase Triplit joins Supabase Supabase Series E 1000 Y Combinator Founders Choose Supabase gm 👋 web3, welcome aboard to Sign in with Web3 (Solana, Ethereum) Announcing the Supabase Remote MCP Server Enterprise speed, enterprise standards with Bolt Cloud + Supabase PostgREST 13 Lovable Cloud + Supabase: The Default Platform for AI Builders Processing large jobs with Edge Functions, Cron, and Queues Defense in Depth for MCP Servers OrioleDB Patent: now freely available to the Postgres community Supabase Launch Week 15 Hackathon Winner Announcement The Vibe Coder's Guide to Supabase Environments Testing for Vibe Coders: From Zero to Production Confidence The Vibe Coding Master Checklist Vibe Coding: Best Practices for Prompting Supabase Auth: Build vs. Buy Top 10 Launches of Launch Week 15 Supabase Launch Week 15 Hackathon Storage: 10x Larger Uploads, 3x Cheaper Cached Egress, and 2x Egress Quota Persistent Storage and 97% Faster Cold Starts for Edge Functions Algolia Connector for Supabase New Observability Features in Supabase Improved Security Controls and A New Home for Security Introducing Branching 2.0 Stripe-To-Postgres Sync Engine as standalone Library Supabase Analytics Buckets with Iceberg Support Create a Supabase backend using Figma Make Introducing JWT Signing Keys Supabase UI: Platform Kit Build a Personalized AI Assistant with Postgres Announcing Multigres: Vitess for Postgres Building on open table formats Open Data Standards: Postgres, OTel, and Iceberg Simplifying back-end complexity with Supabase Data APIs PostgreSQL Event Triggers without superuser access Top 10 Launches of Launch Week 14 Supabase MCP Server Data API Routes to Nearest Read Replica Declarative Schemas for Simpler Database Management Realtime: Broadcast from Database Keeping Tabs on What's New in Supabase Studio Edge Functions: Deploy from the Dashboard + Deno 2.1 Automatic Embeddings in Postgres Introducing the Supabase UI Library Supabase Auth: Bring Your Own Clerk Postgres Language Server: Initial Release Migrating from Fauna to Supabase Migrating from the MongoDB Data API to Supabase Dedicated Poolers Postgres as a Graph Database: (Ab)using pgRouting AI Hackathon at Y Combinator Calendars in Postgres using Foreign Data Wrappers Supabase Launch Week 13 Hackathon Winners How to Hack the Base! Running Durable Workflows in Postgres using DBOS database.build v2: Bring-your-own-LLM Restore to a New Project Hack the Base! with Supabase Top 10 Launches of Launch Week 13 Supabase Queues High Performance Disk Supabase Cron Supabase CLI v2: Config as Code Supabase Edge Functions: Introducing Background Tasks, Ephemeral Storage, and WebSockets Supabase AI Assistant v2 OrioleDB Public Alpha Executing Dynamic JavaScript Code on Supabase with Edge Functions ClickHouse Partnership, improved Postgres Replication, and Disk Management
Postgres Realtime location sharing with MapLibre
Thor Schaeff · 2024-07-04 · via Supabase Blog

Postgres Realtime location sharing with MapLibre

This tutorial is building upon the previous learnings on Postgis and Supabase and adding Supabase Realtime on top. If you're new to this topic, we recommend you review the following first:

In this tutorial, you will learn to

  • Use a Supabase Edge Function to build a Telegram Bot that captures live location data.
  • Use an RPC (remote procedure call) to insert location data into Postgres from an Edge Function.
  • Use Supabase Realtime to listen to changes in the database.
  • Use MapLibre GL JS in React to draw live location data onto the map.

In this section, you will create an Edge Function that will capture live location data from a Telegram Bot. The Telegram Bot will send location data to the Edge Function, which will then insert the data into Supabase.

For a detailed guide on how to create a Telegram Bot, please refer to our docs here.

You can find the production ready code for the Telegram Bot Supabase Edge Function on GitHub. This is the relevant code that listens to the live location updates and writes them to the database:

/supabase/functions/telegram-bot/index.ts


_58

import { Bot, webhookCallback } from 'https://deno.land/x/grammy@v1.20.3/mod.ts'

_58

import { createClient } from 'jsr:@supabase/supabase-js@2.39.7'

_58

import { Database } from '../_shared/database.types.ts'

_58

_58

const token = Deno.env.get('BOT_TOKEN')

_58

if (!token) throw new Error('BOT_TOKEN is unset')

_58

_58

const supabase = createClient<Database>(

_58

Deno.env.get('SUPABASE_URL')!,

_58

Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!

_58

)

_58

_58

const bot = new Bot(token)

_58

// ...

_58

_58

bot.on('edit:location', async (ctx) => {

_58

const {

_58

location,

_58

from: { id: user_id },

_58

edit_date,

_58

} = ctx.update.edited_message!

_58

if (location) {

_58

// Insert into db

_58

const { error } = await supabase.rpc('location_insert', {

_58

_user_id: user_id,

_58

_lat: location.latitude,

_58

_long: location.longitude,

_58

_timestamp: edit_date,

_58

})

_58

if (

_58

error &&

_58

error.message !==

_58

'null value in column "event_id" of relation "locations" violates not-null constraint' &&

_58

error.message !== 'duplicate key value violates unique constraint "locations_pkey"'

_58

) {

_58

return console.log(`edit:location:insert:error:user:${user_id}: ${error.message}`)

_58

}

_58

}

_58

return

_58

})

_58

_58

const handleUpdate = webhookCallback(bot, 'std/http')

_58

_58

Deno.serve(async (req) => {

_58

const headers = req.headers

_58

try {

_58

const url = new URL(req.url)

_58

if (url.searchParams.get('secret') !== Deno.env.get('FUNCTION_SECRET')) {

_58

return new Response('not allowed', { status: 405 })

_58

}

_58

_58

return await handleUpdate(req)

_58

} catch (err) {

_58

console.log(headers)

_58

console.error(err)

_58

}

_58

return new Response()

_58

})


Use an RPC to insert location data into Postgres#

The edge function above uses an RPC (remote procedure call) to insert the location data into the database. The RPC is defined in our Supabase Migrations. The RPC first validates that the user has an active session and then inserts the location data into the locations table:


_10

CREATE OR REPLACE FUNCTION public.location_insert(_timestamp bigint, _lat double precision, _long double precision, _user_id bigint)

_10

RETURNS void AS $$

_10

declare active_event_id uuid;

_10

begin

_10

select event_id into active_event_id from public.sessions where user_id = _user_id and status = 'ACTIVE'::session_status;

_10

_10

INSERT INTO public.locations(event_id, user_id, created_at, lat, long, location)

_10

VALUES (active_event_id, _user_id, to_timestamp(_timestamp), _lat, _long, st_point(_long, _lat));

_10

end;

_10

$$ LANGUAGE plpgsql VOLATILE;


In this section, you will use Supabase Realtime to listen to changes in the database. The Realtime API is a powerful tool that allows you to broadcast changes in the database to multiple clients.

The full client-side code for listening to the realtime changes and drawing the marker onto the map is available on GitHub.

We're going to brake it down into a couple of steps:

Since we're working in React, we will set up the Realtime subscription in the useEffect hook. If you're using Next.js, it's important to mark this with use client as we will need client-side JavaScript to make this happen:

/app/app/realtimemap/%5Bevent%5D/page.tsx


_41

// ...

_41

export default function Page({ params }: { params: { event: string } }) {

_41

const supabase = createClient<Database>()

_41

const [locations, setLocations] = useState<{

_41

[key: string]: Tables<'locations'>

_41

} | null>(null)

_41

const locationsRef = useRef<{

_41

[key: string]: Tables<'locations'>

_41

} | null>()

_41

locationsRef.current = locations

_41

_41

useEffect(() => {

_41

// Listen to realtime updates

_41

const subs = supabase

_41

.channel('schema-db-changes')

_41

.on(

_41

'postgres_changes',

_41

{

_41

event: 'INSERT', // Listen only to INSERTs

_41

schema: 'public',

_41

table: 'locations',

_41

filter: `event_id=eq.${params.event}`,

_41

},

_41

(payload) => {

_41

const loc = payload.new as Tables<'locations'>

_41

const updated = {

_41

...locationsRef.current,

_41

[loc.user_id.toString()]: loc,

_41

}

_41

_41

setLocations(updated)

_41

}

_41

)

_41

.subscribe()

_41

console.log('Subscribed')

_41

_41

return () => {

_41

subs.unsubscribe()

_41

}

_41

}, [])

_41

// ...


The realtime subscription listener above updates the state of the locations object with the new location data, anytime it is inserted into the table. We can now use react-map-gl to easily draw the location markers onto the map:

/app/app/realtimemap/%5Bevent%5D/page.tsx


_33

// ...

_33

<Map

_33

className="map"

_33

cooperativeGestures={true}

_33

initialViewState={{

_33

longitude: 103.852713,

_33

latitude: 1.285727,

_33

zoom: 13,

_33

}}

_33

mapStyle={{

_33

version: 8,

_33

glyphs: 'https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf',

_33

sources: {

_33

protomaps: {

_33

attribution:

_33

'<a href="https://github.com/protomaps/basemaps">Protomaps</a> © <a href="https://openstreetmap.org">OpenStreetMap</a>',

_33

type: 'vector',

_33

url: 'pmtiles://https://<project_ref>.supabase.co/functions/v1/maps-private/my_area.pmtiles',

_33

},

_33

},

_33

transition: {

_33

duration: 0,

_33

},

_33

// @ts-ignore

_33

layers: layers('protomaps', 'light'),

_33

}}

_33

// @ts-ignore

_33

mapLib={maplibregl}

_33

>

_33

{Object.entries(locations).map(([key, value]) => (

_33

<Marker key={key} longitude={value.long} latitude={value.lat} color="red" />

_33

))}

_33

</Map>


That's it, this is how easy it is to add realtime location data to your applications using Supabase! We can't wait to see what you will build!

Supabase Realtime is ideal for broadcasting location data to multiple clients. Combined with the power of PostGIS and the broader Postgres extension ecosystem, its's a powerful solution for all your geospatial needs!

Want to learn more about Maps and PostGIS? Make sure to follow our Twitter and YouTube channels to not miss out! See you then!