fn_phone uploads: photos, videos and voice notes on FiveDock
Send fn_phone’s photos, videos and voice notes to FiveDock instead of your database: one config line, plus the fivedock agent or an API token.
By Termi
- fn_phone
- Uploads
- Lua
On this page
- Where fn_phone keeps media
- Upload through the fivedock agent
- Upload with an API token
- Change it from the game
- Check that it works
- What fn_phone uploads
- Photos still on Fivemanage
- If uploads fail
- Common questions
- Does fn_phone work with FiveDock?
- Do I need an API token for fn_phone?
- Can fn_phone still upload to Fivemanage?
- Can players use FiveDock links as ringtones?
- Is Config.Fivedock the same setting?
fn_phone is our own phone resource for FiveM. Out of the box it keeps every photo, video and voice note in your database. One line in its config sends them to FiveDock, and the database keeps only the link. The upload runs on the server through fn_bridge, so you edit no fn_phone files and no token ever reaches a player.
Where fn_phone keeps media
Every file the phone records is a row in fn_phone_media. With Config.Media.provider = 'local', the default, the row’s url column holds the whole file as a data URI, up to 3 MiB for a photo and 12 MiB for a video. The server says so on every start:
[fn_phone] photos are stored in the database (Config.Media.provider = local); use fivedock for a CDNWith provider = 'fivedock', the server hands each file to FN_BRIDGE.MEDIA.Upload in fn_bridge, which uploads it and returns the CDN link. fn_bridge reaches FiveDock in one of two ways. With a token set, it posts the file to https://api.fivedock.dev/api/v3/file/base64, the same base64 address Fivemanage’s v3 API has. With no token and the fivedock agent resource started, it writes the file to its cache folder, hands it to exports.fivedock:upload and deletes it afterwards.
Players never get an upload link. A video recorded on the phone goes to the server first as a latent event, and the server uploads it like a photo.
Upload through the fivedock agent
If the fivedock agent already runs on your server, you have no token to make. The agent signs in with the fda_live_ key from server.cfg, and fn_bridge sends uploads through it whenever no token is set. The agent needs two lines in server.cfg, as the agent guide describes. Put them above ensure fn_phone:
set fivedock_key "fda_live_…"
ensure fivedockThen switch the provider in fn_phone/config.lua and leave token empty:
Media = { provider = 'fivedock', token = '', encoding = 'webp', quality = 0.85, limit = 2000 },Restart fn_phone. Uploads land in the fn_phone folder of your workspace.
Upload with an API token
Without the agent, fn_bridge needs an API token. In the FiveDock panel, open Tokens, create a token with the files:write scope and bind it to your server. It starts with fd_live_. It is not the fda_live_ agent key, which the upload API does not accept.
fn_phone reads the token from Config.Media.token first. If you leave that empty, fn_bridge falls back to a convar in server.cfg, which every script on fn_bridge can use:
set fn_bridge:upload_token "fd_live_…"Use set here. setr replicates the convar to every player’s game. config.lua is safe too, since fn_phone loads it only as a server script. Set provider = 'fivedock' as in the agent section. If a token and the agent are both there, fn_bridge uses the token.
For each file, fn_bridge sends this request:
POST https://api.fivedock.dev/api/v3/file/base64
Authorization: fd_live_…
Content-Type: application/json
{"base64":"UklGR…","filename":"fn_phone_1792756800_482913.webp","path":"fn_phone"}The file name is fn_phone_, the upload time in Unix seconds and a random number. FiveDock answers with the CDN link in data.url, which is where fn_bridge reads it.
Change it from the game
Admin → Server Config has both settings in the Uploads and Web step: Storage is Media.provider and fivedock token is Media.token. The panel never shows a saved token, only whether one is set. Saved values go to the server’s KVP storage and apply on top of config.lua after fn_phone restarts, so a Storage value saved in the game wins over the file.
Check that it works
After the restart, the console no longer prints the line about photos in the database. Take a photo with the camera and open Files in the FiveDock panel: it is in the fn_phone folder, under a name like fn_phone_1792756800_482913.webp. In the database, the newest rows should hold FiveDock links:
SELECT id, kind, LEFT(url, 40) AS url
FROM fn_phone_media
ORDER BY id DESC
LIMIT 10;A url that starts with https://cdn.fivedock.dev/ is on FiveDock. One that starts with data: is in the database: the upload failed, and fn_phone stored the file there. To get an error on the phone instead, add fallback = false to Config.Media; a photo or video that fails to upload is then not saved at all. Voice notes always fall back to the database.
What fn_phone uploads
FiveDock accepts all of these. Screen recordings are the exception on the phone’s side: fn_phone keeps them in its own format in the database, whatever the provider.
Voice notes show up as video
Voice notes are WebM files, the same container fn_phone’s videos use. FiveDock reads a file’s type from its bytes, so the panel lists voice notes under video.
Photos still on Fivemanage
fn_phone dropped its Fivemanage option in version 1.1.11. If your config.lua still says provider = 'fivemanage', change it to 'fivedock' as above. Photos taken before the switch keep their Fivemanage links, and so do photos that fn_phone_migrate brought over from lb-phone or another phone, since the import copies each link as it is. They load for as long as the files stay on Fivemanage. Since 1.1.11, r2.fivemanage.com links no longer work as custom ringtones.
The links sit in the url column of fn_phone_media, and Messages, ads and stories point at those rows by their 16-character key. The migration copies your Fivemanage files with a read-only key and gives you a list of old link → new link. Each row of that list becomes one statement:
UPDATE fn_phone_media
SET url = 'https://cdn.fivedock.dev/f/8Kq2nR4t.webp'
WHERE url = 'https://r2.fivemanage.com/…/IMG_0412.webp';Nothing on Fivemanage is changed or deleted, so you can run the statements whenever you are ready.
If uploads fail
Common questions
Does fn_phone work with FiveDock?
Yes, without edits to its files. Set Config.Media.provider = 'fivedock', then either run the fivedock agent or give fn_phone an fd_live_ token with the files:write scope, in Config.Media.token or in the fn_bridge:upload_token convar. fn_bridge uploads each photo, video and voice note from the server and stores the CDN link.
Do I need an API token for fn_phone?
Not if the fivedock agent runs on the server. With no token set, fn_bridge hands every upload to the agent, which signs in with its own fda_live_ key. You need an fd_live_ token only on a server without the agent.
Can fn_phone still upload to Fivemanage?
No. Version 1.1.11 removed the Fivemanage option, and Config.Media.provider now takes local or fivedock. Old Fivemanage links in fn_phone_media keep loading while the files exist, and FiveDock’s migration copies the files over and lists the new links.
Can players use FiveDock links as ringtones?
Yes. fivedock.dev is the first host in Config.Ringtones.hosts, and subdomains count, so a link on cdn.fivedock.dev passes. The link has to end in a sound file extension such as .mp3 or .ogg. Upload the file in Files, then paste its link in Settings → Sounds → Ringtone on the phone.
Is Config.Fivedock the same setting?
No. Config.Fivedock sends Black Box events, the phone’s logs, to your FiveDock panel. Photos, videos and voice notes follow Config.Media only. With the agent running, both work without a token.