Skip to content
Blog

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

7 min read
  • fn_phone
  • Uploads
  • Lua
On this page

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:

server console
[fn_phone] photos are stored in the database (Config.Media.provider = local); use fivedock for a CDN

With 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:

server.cfg
set fivedock_key "fda_live_…"
ensure fivedock

Then switch the provider in fn_phone/config.lua and leave token empty:

config.lua
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:

server.cfg
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:

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:

SQL
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

  • Photos from the camera, as WebP by default. Config.Media.encoding takes webp, jpg or png, and quality sets the compression, 0.85 by default. The camera needs screencapture or screenshot-basic running.
  • Videos, as WebM with VP9 or VP8 at 1.6 Mbit/s. The camera stops a clip at 30 seconds, so a clip stays around 6 MB.
  • Voice notes and voicemail, as WebM with Opus audio, up to 400 KiB each.
  • Images added to Photos from a link: PNG, JPEG, WebP or GIF up to 2.25 MiB. The server downloads its own copy and uploads it, so the photo survives a Discord link that expires.

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:

SQL
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

  • Photos still land in the database. fn_phone stores a photo in the database when its upload fails, so a mistyped token, a token without files:write and a full workspace all look the same on the phone. A workspace over its storage limit refuses uploads with 429. Check the token in Config.Media.token or fn_bridge:upload_token, and the storage in the panel.
  • The agent runs, but uploads still fail. A token takes priority over the agent. If Config.Media.token or fn_bridge:upload_token holds an old token, fn_bridge sends that one. Clear both to upload through the agent.
  • The console still prints [fn_phone] photos are stored in the database (Config.Media.provider = local); use fivedock for a CDN. A Storage value saved in Admin → Server Config overrides config.lua. Change it there, or press Reset next to it.
  • The camera takes no photos. fn_phone needs screencapture or screenshot-basic for the camera. Check that one of them is started.

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.

All articles