Where the Facebook client token goes in a Flutter app
Last updated August 7, 2026
What the client token is
The client token identifies your app when the Facebook SDK calls Meta's app-level endpoints. Meta's own wording: client tokens "identify your app when calling app-level APIs from native or desktop apps", and they cannot be used on their own, because "you must combine them with your App ID by appending the token to the end of the App ID, separated by a pipe symbol". The SDK does that combining for you. What it cannot do is guess either value.
It is not your app id. Two different values, two different configuration keys, and the SDK needs both. Paste the app id into the client token key and the app has no valid client token, which fails exactly the way leaving the key out fails: in silence.
You do not need to hide it. Meta states it plainly: "Because client tokens are embedded in apps, they are not secret." It ships inside your app binary by design, so it can live in your repository alongside the rest of your platform configuration.
Where to get it
From the App Dashboard, for the app you want the events to land in. Meta's client-token documentation gives the path: on the Dashboard, go to Settings > Advanced > Security > Client token.
Check which app you have open before you copy. A client token from a different app in the same business account looks entirely plausible, pastes without complaint, and will not work.
Android needs two files, not one
This is where the time goes. The token has to be in a string resource, and the manifest has to point at that resource. One without the other does nothing.
The string resources
In android/app/src/main/res/values/strings.xml, or the matching debug or release build flavor file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="facebook_app_id">[APP_ID]</string>
<string name="facebook_client_token">[CLIENT_TOKEN]</string>
<string name="fb_login_protocol_scheme">fb[APP_ID]</string>
<string name="app_name">[APP_NAME]</string>
</resources>The manifest references
The string resources alone do nothing. What the SDK reads is the meta-data entries in AndroidManifest.xml, and those entries are what reference your strings. Leave them out and the values sit in your resources with nothing looking them up.
Both go directly under <application>:
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="@string/facebook_client_token"/>If you added the strings and stopped there, this is your bug, and nothing in the build or the logs will point at it.
The build flavor trap
If your app has build flavors, check which strings.xml you edited. A flavor's resource directory overrides the main one, so a client token placed in the wrong flavor's file is simply not present in the build you are running.
This one hides well. The file open on your screen is correct. The value is right there, spelled correctly, in a file that exists. It is just not in the resource set your installed build was assembled from.
Build the flavor you are testing, then check the merged manifest and merged resources the build produced rather than the source files you edited. That is the check that answers the question.
Neither this nor the manifest entries appear in Meta's client-token documentation, and neither is a criticism of it: that page describes the SDK generically, for every platform that embeds it. Both traps live in the Android project that the Flutter tool generates for you, which is the part nobody documents.
iOS: Info.plist
One file, and no indirection to get wrong. All of it goes in Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb[APP_ID]</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>[APP_ID]</string>
<key>FacebookClientToken</key>
<string>[CLIENT_TOKEN]</string>
<key>FacebookDisplayName</key>
<string>[APP_NAME]</string>Two of those keys matter for this page: FacebookAppID and FacebookClientToken. The rest of the block is the standard Facebook configuration, reproduced here so you can compare it against what your project already has.
There is no manifest-style indirection on iOS. The value sits directly in the key the SDK reads.
When the token is wrong
Nothing tells you. The app builds. The SDK initializes. logEvent returns without an error. Events Manager stays empty.
A missing or wrong client token is one of the most common reasons events never arrive, and it produces no signal at the call site. Compare the value character by character against the App Dashboard before you look anywhere else.
If the token checks out and events still are not landing, the next page works through the rest in order, configuration then transport then attribution, so you stop guessing which layer you are in: Facebook events not showing in Events Manager.
Verify your setup
- The client token in your app matches Settings > Advanced > Security > Client token for the same app in the App Dashboard
- Android: facebook_client_token is set in the strings.xml of the flavor you are actually building
- Android: the com.facebook.sdk.ClientToken meta-data entry is present under the application element in AndroidManifest.xml
- Android: you checked the merged manifest and merged resources from the build, not the source files you edited
- iOS: FacebookClientToken is set in Info.plist
- The app id and the client token are each in their own key, and neither value has been pasted into the other
Meta's reference documentation
Plugin API reference
Still stuck?
It is a plugin defect
If the plugin is doing something the native Facebook SDK does not, that is our bug. Open an issue and we fix it. Free, always, no conditions.
Open a GitHub issueIt is a usage question
Configuration and integration questions are best asked where other developers can find the answer later.
Ask on StackOverflowYour numbers are wrong and money is moving
If Meta install campaigns are spending and the attribution does not add up, that is a different problem from a broken build. One hour, 300 USD, credited against the audit if you go ahead.
See the diagnostic and audit