Flame Blog
How to manually publish messages to the Pub/Sub emulator
Calling the Pub/Sub emulator directly via the HTTP API.
Published April 24, 2026
By Val
When you have Pub/Sub functions defined, a matching topic is automatically provisioned in the emulator.
export const pubsubFunction = functions.pubsub.onMessagePublished(
{ topic: 'my-topic' },
event => {
console.log({ event, json: event.data.message.json })
}
) export const pubsubFunction = functions.pubsub
.topic('my-topic')
.onPublish(message => {
console.log({ message, json: message.json })
}) The Pub/Sub emulator runs by default on port 8085 and you can publish
messages to it using the Pub/Sub SDK in your favorite language, i.e.:
import { PubSub } from '@google-cloud/pubsub'
const pubsub = new PubSub({
projectId: 'my-project',
apiEndpoint: 'localhost:8085',
})
// Can also use an empty constructor with `GOOGLE_CLOUD_PROJECT`
// and `PUBSUB_EMULATOR_HOST` environment variables set.
// const pubsub = new PubSub()
const topic = pubsub.topic('my-topic')
await topic.publishMessage({
json: {
foo: 'bar',
},
})
But in this post I want to go deeper into the weeds and show how to use the emulator’s HTTP API directly.
Publishing a message
To publish a message to a topic, use the :publish endpoint:
curl -X POST 'http://127.0.0.1:8085/v1/projects/my-project/topics/my-topic:publish' \
-H 'Content-Type: application/json' \
-d '{"messages": [{"data": "eyJmb28iOiJiYXIifQ=="}]}'
The data field inside each message must be Base64-encoded. Here, the
payload is {"foo": "bar"}.
Buffer.from(JSON.stringify({ foo: 'bar' })).toString('base64')
// 'eyJmb28iOiJiYXIifQ=='
To deal with Base64-encoding in the same command, we can do the following:
curl -X POST 'http://127.0.0.1:8085/v1/projects/my-project/topics/my-topic:publish' \
-H 'Content-Type: application/json' \
-d '{"messages": [{"data": "'$(echo '{"foo": "bar"}' | base64)'"}]}'
You can also include message attributes:
curl -X POST "http://127.0.0.1:8085/v1/projects/my-project/topics/my-topic:publish" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"data": "eyJmb28iOiJiYXIifQ==",
"attributes": {
"foo": "bar"
}
}
]
}'
The endpoint will return the message IDs of the published messages:
{
"messageIds": ["1"]
}
Calling the underlying function directly
If you want to bypass the Pub/Sub emulator entirely and directly call the function behind the topic, check out our dedicated guide to calling Firebase emulator functions.
Stop guessing with Flame ✨
Maybe you don’t want to bother with cURL commands and Base64-encoding when debugging your Pub/Sub functions.
This is why we built Flame, a Firebase emulator UI with everything
that’s missing from localhost:4000.
See all your Pub/Sub topics and task queues at a glance, compose messages with a friendly UI, and publish directly to the emulator. No Base64-encoding required.
Flame gives you the Pub/Sub UI that’s missing from localhost:4000, and also
comes with an improved UI for Firebase Auth, Firestore, Functions, and more.
If that sounds exciting to you, give Flame a try!