Documentation
Guides
Realtime WebSocket

Realtime WebSocket

Moontraze RealTime lets your app receive live updates whenever documents are created, updated, or deleted — no polling needed.

Perfect for:

  • Chat apps (new messages appear instantly)
  • Notifications
  • Live dashboards
  • Collaborative editing

1. Endpoint

wss://api.moontraze.com/ws?projectId=<PROJECT_ID>&token=<USER_JWT>

Replace with your own values:

PlaceholderWhere to find it
<PROJECT_ID>Dashboard → Project Settings → API Keys → Project ID
<USER_JWT>A valid user JWT returned by your login endpoint (e.g. /api/auth or your own auth flow)

Both projectId and token are required. Missing either → connection closed with code 1008.

💡 Tip: Moontraze Cloud host is api.moontraze.com. Just plug in your projectId and token.


2. Connect

JavaScript / Node

const API_HOST = 'api.moontraze.com';        
const PROJECT_ID = 'your_project_id';       
const JWT = 'user_jwt_token';               
 
const ws = new WebSocket(
  `wss://${API_HOST}/ws?projectId=${PROJECT_ID}&token=${JWT}`
);
 
ws.onopen = () => console.log('connected');
 
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  console.log('event:', msg);
};
 
ws.onclose = () => console.log('disconnected');

Dart / Flutter

import 'package:web_socket_channel/web_socket_channel.dart';
 
final apiHost = 'api.moontraze.com';          // ← your host 
final projectId = 'your_project_id';         // ← your projectid
final jwt = 'user_jwt_token';                // ← login 
 
final uri = Uri.parse(
  'wss://$apiHost/ws?projectId=$projectId&token=$jwt'
);
final channel = WebSocketChannel.connect(uri);
await channel.ready;
 
channel.stream.listen((raw) {
  final msg = jsonDecode(raw);
  print('event: $msg');
});

3. Subscribe to a Path

After connecting, subscribe to any database path:

{ "action": "subscribe", "path": "chats/uid1_uid2" }

Server responds:

{ "type": "subscribed", "path": "chats/uid1_uid2" }

Path patterns

PatternMatches
chats/uid1_uid2Exact document/collection
chats/uid1_uid2/**That path and everything under it
chats/*One level under chats/
users/{uid}/messagesTemplate — {uid} matches any single segment
* or **Everything (use with caution)

4. Receive Events

When someone writes to your DB via /api/db (POST/PUT/DELETE), matching subscribers receive:

{
  "type": "created",
  "path": "chats/uid1_uid2/msg_123",
  "data": {
    "path": "chats/uid1_uid2/msg_123",
    "docId": "msg_123",
    "data": { "fromUid": "uid1", "text": "hello", "...": "..." }
  },
  "ts": 1737052800000
}

Event types

typeFired when
createdPOST /api/db succeeded
updatedPUT /api/db succeeded
deletedDELETE /api/db on a document
field_deletedDELETE /api/db?field=...
collection_deletedWhole collection deleted

5. Unsubscribe

{ "action": "unsubscribe", "path": "chats/uid1_uid2" }

6. Keepalive

  • Server sends a ping every 30 seconds
  • Client must pong automatically (browsers do this natively)
  • Client can also send:
{ "action": "ping" }

Server responds with:

{ "type": "pong", "ts": 1737052800000 }

7. Complete Example — Live Chat

// ─── Config ───
const API_HOST   = 'api.moontraze.com';        // ← host
const PROJECT_ID = 'your_project_id';         // ← dashboard 
const JWT        = 'user_jwt_token';          // ← login 
 
// 1. Connect
const ws = new WebSocket(
  `wss://${API_HOST}/ws?projectId=${PROJECT_ID}&token=${JWT}`
);
 
// 2. Subscribe on connect
ws.onopen = () => {
  ws.send(JSON.stringify({
    action: 'subscribe',
    path: 'chats/**'
  }));
};
 
// 3. Handle events
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
 
  if (msg.type === 'created' && msg.path.startsWith('chats/')) {
    appendMessageToUI(msg.data.data);
  }
};
 
// 4. Cleanup
window.addEventListener('beforeunload', () => ws.close());

8. Rules & Security

  • Subscriptions are per-project scoped — you only receive events from your project.
  • JWT is verified on connect — expired token → connection closed.
  • Rules engine is NOT applied to WebSocket events. If you need per-field authorization, filter on the client.

9. Limits

LimitValue
Max connections per projectSoft limit — 1000 (contact us)
Max subscriptions per client100
Ping interval30 s
Auto-disconnect on dead client30–60 s

10. Troubleshooting

SymptomCauseFix
close 1008: projectId and token requiredMissing query paramsAdd ?projectId=...&token=...
close 1008: Invalid tokenJWT expired or wrong secretLogin again, get fresh JWT
Connected but no eventsSubscribed to wrong pathUse chats/** to test
Events fire but UI doesn't updatePayload shape mismatchCheck msg.data.data vs msg.data

Related