Debug School

Abhishek singh
Abhishek singh

Posted on

Traccar Integration — Complete Guide

Traccar Integration — Complete Guide

  1. What is Traccar & Why It's Here Traccar is an open-source GPS tracking server. In Motoshare, it is used to:

Register each vehicle's GPS device (identified by its IMEI number)
Track live vehicle position (latitude, longitude, speed, etc.)
Let partners open a live tracking map in the browser

  1. Architecture

Mobile/Web App


Laravel API (motoshare-web)

├── TraccarService ──► Traccar Server HTTP API (port 8082)
│ /api/users
│ /api/devices
│ /api/positions
│ /api/session
│ /api/session/token

├── addvechicles table (stores imei + traccar_device_id)
└── users table (stores traccar_password)
Two key database columns added by migrations:

Table Column Purpose
addvechicles traccar_device_id Cached Traccar internal device ID (skips IMEI lookup on every position call)
users traccar_password Stored Traccar password for generating per-user JWT tokens

  1. Configuration (.env Variables) Add these to your .env file:

Traccar server URL — the backend API (Laravel calls this internally)

TRACCAR_API_URL=http://localhost:8082

Traccar admin credentials (must be a Traccar admin account)

TRACCAR_API_ADMIN_EMAIL=admin@example.com
TRACCAR_API_ADMIN_PASSWORD=your_admin_password

Traccar web UI URL (browser-facing, for the map redirect)

TRACCAR_WEB_URL=http://localhost:8082

HTTP timeout in seconds

TRACCAR_API_TIMEOUT=10

Set false on local dev if Traccar has a self-signed SSL cert

TRACCAR_VERIFY_SSL=true

Master switch — set true to enable the integration

TRACCAR_ENABLED=true
Important: TRACCAR_API_URL and TRACCAR_WEB_URL can be different. API URL is what Laravel connects to (may be internal network). Web URL is what the browser opens (must be publicly reachable).

  1. All API Endpoints 4.1 Get Traccar JWT Token

GET /api/traccar/token
Auth: Sanctum token required
What it does: Generates a JWT for the logged-in user so the frontend can open the Traccar map UI.

Response:

{ "traccar_token": "eyJhbGciOi..." }
Usage (frontend):

// Open Traccar map for logged-in user
const res = await axios.get('/api/traccar/token');
window.open(${TRACCAR_WEB_URL}?token=${res.data.traccar_token});
4.2 Get Live Vehicle Position

GET /api/vehicles/{vehicleId}/position
Auth: Sanctum token required
What it does: Returns the latest GPS position for a vehicle by its Motoshare vehicle ID.

Response:

{
"vehicle_id": 42,
"imei": "123456789012345",
"latitude": 12.9716,
"longitude": 77.5946,
"speed": 0.0,
"course": 180.0,
"accuracy": 5.2,
"altitude": 920.0,
"device_time": "2026-06-02T10:30:00.000+0000",
"fix_time": "2026-06-02T10:29:58.000+0000",
"attributes": { "ignition": true, "motion": false }
}
Error responses:

{ "error": "Vehicle not found or no GPS device" } // 404 — vehicle missing or no IMEI set
{ "error": "No position data available" } // 404 — device registered but no GPS fix yet
{ "error": "Internal server error" } // 500
4.3 Get Live Position by Booking

GET /api/bookings/{bookingId}/position
Auth: Sanctum token required
What it does: Same as above but looks up the vehicle through a booking ID — useful for riders tracking their rented vehicle.

Response: Same fields as 4.2 plus:

{ "booking_id": 99, "vehicle_id": 42, ... }
4.4 Open Tracker in Browser (Web Route)

GET /tracker/launch
Auth: Keycloak session (kc_auto middleware)
What it does: Generates a Traccar JWT for the logged-in user, then serves a bridge page (traccar_bridge.blade.php) that:

Deletes any existing Traccar browser session (so the JWT always wins)
Redirects to TRACCAR_WEB_URL?token=
How to trigger from sidebar/menu:

Open Tracker

  1. How the Service Works — Internal Flows 5.1 Registering a Vehicle's GPS Device Triggered when: A vehicle is added/updated with an IMEI number via saveTraccarDevice().

uploadvechiclecontroller::update_vehiclestab()

└─► UtilityFunctionsController::saveTraccarDevice($request, $email, $vehicleId)

└─► TraccarService::saveDevice($request, $email, $vehicleId)

├─ getUserByEmail($email) → find/create Traccar user account
├─ syncDevice($request, ...) → create or update Traccar device
├─ linkDeviceToUser(...) → link device to user in Traccar
└─ update addvechicles.traccar_device_id ← cached for fast lookups
Request fields needed: imei, brand, vehicleType, model

5.2 Getting Position (Fast Path)
Once traccar_device_id is cached on the vehicle:

GET /api/vehicles/{id}/position

└─► resolveVehiclePosition($vehicle)

├─ IF traccar_device_id set → getLatestPositionByDeviceId(id) [1 HTTP call]
└─ IF only imei set → getDeviceByUniqueId(imei) [2 HTTP calls]
→ getLatestPositionByDeviceId(id)
Always register devices via saveTraccarDevice — it sets traccar_device_id and halves position lookup cost.

5.3 JWT Token Generation for Map Access

ensureUserToken($email)

├─ resolveTraccarPassword($email, $laravelUser)
│ ├─ IF traccar_password stored in users table → return it [0 HTTP calls]
│ ├─ IF Traccar account exists but no stored password → provisionTraccarPassword()
│ └─ IF no Traccar account → createUser() + store password

├─ getSessionJwt($email, $password)
│ ├─ POST /api/session (creates session cookie)
│ └─ POST /api/session/token (exchanges cookie for JWT)

├─ IF JWT fails (stale password) → retryWithFreshPassword() → getSessionJwt()
└─ IF all fails → adminSessionJwt() (admin fallback)

  1. TraccarService Public Methods Reference Method Description Called From saveDevice($request, $email, $vehicleId) Register/update a GPS device for a vehicle saveTraccarDevice() wrappers ensureUserToken($email) Get a Traccar JWT for a user getTraccarToken, /tracker/launch getUserByEmail($email) Fetch Traccar user by email Internal createUser($name, $email, $password) Create a new Traccar user account Internal getDeviceByUniqueId($imei) Fetch Traccar device by IMEI Internal createDevice($name, $imei, ...) Register a new GPS device Internal updateDevice($deviceId, ...) Update an existing GPS device Internal linkDeviceToUser($userId, $deviceId) Give user permission to see device Internal getLatestPosition($imei) Get last GPS position by IMEI resolveVehiclePosition getLatestPositionByDeviceId($id) Get last GPS position by device ID (fast) resolveVehiclePosition
  2. Database Migrations Two migrations were added:

add_traccar_device_id_to_addvechicles_table

ALTER TABLE addvechicles ADD COLUMN traccar_device_id INT NULL;
add_traccar_password_to_users_table

ALTER TABLE users ADD COLUMN traccar_password VARCHAR(255) NULL;
Run with: php artisan migrate

  1. How to Add GPS Tracking to a Vehicle (Step by Step) Step 1 — Vehicle must have an IMEI field set When adding/editing a vehicle, pass imei in the request body.

Step 2 — saveTraccarDevice is called automatically
uploadvechiclecontroller.php:1662 calls $this->utilityController->saveTraccarDevice($request, $useremail, $vehicleId) after vehicle save.

Step 3 — Verify registration worked
Check addvechicles table: traccar_device_id should be non-null for that vehicle.

Step 4 — Poll position from frontend

// Every 10 seconds
setInterval(async () => {
const res = await axios.get(/api/vehicles/${vehicleId}/position);
map.setCenter({ lat: res.data.latitude, lng: res.data.longitude });
}, 10000);

  1. Common Issues & Fixes Symptom Cause Fix No position data available (404) Device registered but GPS hasn't sent data yet Wait for GPS hardware to get a satellite fix and transmit Vehicle not found or no GPS device (404) imei column is null/empty in DB Set IMEI when adding/editing the vehicle JWT works once, then fails Traccar session expired ensureUserToken auto-retries with a fresh password; if still failing check users.traccar_password column traccar_device_id is null saveTraccarDevice was never called or IMEI was blank Re-save the vehicle with a valid IMEI Admin fallback used constantly Traccar user accounts not provisioning Check logs for provisionTraccarPassword - PUT failed; verify admin credentials in .env SSL errors on local dev Self-signed cert Set TRACCAR_VERIFY_SSL=false in .env Traccar returns all users instead of filtered Admin token bypasses ?email= filter This is expected — the service filters client-side, works correctly /tracker/launch shows blank TRACCAR_WEB_URL not set Add TRACCAR_WEB_URL to .env and run php artisan config:clear
  2. Quick Checklist for a Fresh Setup

☐ Traccar server running and accessible from Laravel server
☐ TRACCAR_API_URL set (internal network URL)
☐ TRACCAR_WEB_URL set (browser-accessible URL)
☐ TRACCAR_API_ADMIN_EMAIL + TRACCAR_API_ADMIN_PASSWORD set
☐ TRACCAR_ENABLED=true
☐ php artisan migrate (adds traccar_device_id + traccar_password columns)
☐ php artisan config:clear
☐ Add a vehicle with a valid IMEI → verify traccar_device_id populates in DB
☐ Call GET /api/traccar/token → verify JWT returned
☐ Call GET /api/vehicles/{id}/position → verify coordinates returned

Top comments (0)