Kebechet.Maui.Facebook.Core 1.0.0

Prefix Reserved
dotnet add package Kebechet.Maui.Facebook.Core --version 1.0.0
                    
NuGet\Install-Package Kebechet.Maui.Facebook.Core -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Kebechet.Maui.Facebook.Core" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Kebechet.Maui.Facebook.Core" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Kebechet.Maui.Facebook.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Kebechet.Maui.Facebook.Core --version 1.0.0
                    
#r "nuget: Kebechet.Maui.Facebook.Core, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Kebechet.Maui.Facebook.Core@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Kebechet.Maui.Facebook.Core&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Kebechet.Maui.Facebook.Core&version=1.0.0
                    
Install as a Cake Tool

"Buy Me A Coffee"

Maui.Facebook.Core

NuGet Version NuGet Downloads unit-tests build-demo Last updated (main) Twitter

.NET MAUI wrapper for the Facebook (Meta) Core SDKs - App Events, SDK settings and the anonymous app-device id - on Android and iOS.

It exists because Meta's attribution partners (RevenueCat, Adjust, AppsFlyer, ...) need the Facebook anonymous id (anon_id / $fbAnonId) before they will deliver an in-app event to Meta, and that id only comes from Meta's own SDK. There is no maintained MAUI binding of that SDK; this is one.

Package What Native SDK
Kebechet.Maui.Facebook.Core the cross-platform wrapper you reference -
Kebechet.Maui.Facebook.Core.Android binding com.facebook.android:facebook-core 18.3.0
Kebechet.Maui.Facebook.Core.iOS binding FBSDKCoreKit 18.1.1 (+ FBSDKCoreKit_Basics, FBAEMKit)

Usage

Register it in MauiProgram.cs:

builder.Services.AddFacebookCore();

Initialize once at startup with the values from the Meta App Dashboard (App ID, and the Client Token from Settings → Advanced):

public partial class App : Application
{
    private readonly IFacebookCoreService _facebookCore;

    public App(IFacebookCoreService facebookCore)
    {
        InitializeComponent();
        _facebookCore = facebookCore;
    }

    protected override void OnStart()
    {
        _facebookCore.Initialize(appId: "<FacebookAppId>", clientToken: "<FacebookClientToken>");
        base.OnStart();
    }
}

No Info.plist keys and no AndroidManifest.xml meta-data are required: the wrapper configures the SDK programmatically. (The Android SDK still logs an informational "Failed to auto initialize the Facebook SDK" at process start because the manifest carries no app id - that is expected, the explicit Initialize call is what configures it.)

Hand the anonymous id to your attribution partner

var anonymousId = _facebookCore.AnonymousId;   // "XZ" + UUID, persisted per install, works with ATT denied

// RevenueCat: the attribute its Meta Ads integration requires before it delivers events to Meta
_revenueCatBilling.SetAttributes(new Dictionary<string, string> { ["$fbAnonId"] = anonymousId! });

Log events

_facebookCore.UserId = accountId;                          // attached to every later event; null clears it
_facebookCore.LogEvent("fb_mobile_complete_registration");
_facebookCore.LogEvent("level_up", new Dictionary<string, object> { ["level"] = 3 }, valueToSum: 3);
_facebookCore.LogPurchase(9.99m, "EUR");
_facebookCore.Flush();
_facebookCore.SetAutoLogAppEventsEnabled(consented);
_facebookCore.SetAdvertiserIdCollectionEnabled(consented);

On iOS request App Tracking Transparency yourself (ATTrackingManager.RequestTrackingAuthorization) before the first events - since Facebook iOS SDK 17 the SDK reads the ATT status on its own. SetAdvertiserTrackingEnabled is kept for source compatibility with older Meta docs but is [Obsolete]: the bound 18.x SDK ignores the setter and logs a deprecation warning; Android never had an equivalent.

Full API with remarks per member: IFacebookCoreService.

Dummy classes

Windows, MacCatalyst and the plain net10.0 target ship a no-op implementation, so you never have to guard calls by platform. Their members return true for bool and null for nullable strings.

Exception behavior

  • The library throws only for developer mistakes.
  • Every native failure is caught and reported through ILogger<FacebookCoreService> at Error, and the member returns the default of its type. Nothing native ever surfaces as an exception in your code.

⚠️ iOS Local debugging

Because of MAUI and VS bugs:

it is not possible to run your app with hot-restart (direct local iOS deploy from VS for Windows).

Demo and on-device harness

demo/DemoApp is a MAUI Blazor Hybrid app whose single page runs every wrapper member against the real SDK and reports pass/fail per member. Because the wrapper never throws, the harness judges each check by what the wrapper logged: a check that logs a warning or error fails.

It is scriptable, so a device run needs no tapping:

# Android
adb shell am start -n com.kebechet.demoapp/.MainActivity --es appId <id> --es clientToken <token> --ez autoRun true
adb logcat -d | grep "\[Harness\]"

# iOS (from a Mac; the app must be built and installed with a development identity first)
xcrun devicectl device process launch --console --device <udid> com.kebechet.demoapp -- --appId <id> --autoRun true

Verified: all 12 checks pass on an Android 16 (API 36) emulator and on a physical iPhone 11.

⚠️ Do not pass an empty extra (--es clientToken "") - the shell drops it and am misparses the rest. Leave the flag out instead; the app defaults the token to empty.

Automated SDK updates

Two independent workflows watch Meta's native SDKs and each turn a new release into one standalone pull request that is ready to merge when it opens:

Workflow Watches Runner
TryBumpAndroid (.github/workflows/try-bump-android.yml) com.facebook.android:facebook-core on Maven Central ubuntu
TryBumpIOS (.github/workflows/try-bump-ios.yml) facebook/facebook-ios-sdk GitHub releases macOS

Both run daily and on demand (workflow_dispatch takes an optional explicit version). A run bumps the binding csproj only. The wrapper csproj is asserted byte-identical before anything is committed, so main never references a binding that is not on nuget.org yet.

The iOS binding is curated by hand (src/Maui.Facebook.Core.iOS/ApiDefinitions.cs), not generated: FBSDKCoreKit exposes 220 headers and the wrapper needs three types. A bump therefore swaps and slims the xcframeworks and rebuilds. Because bgen never reads the headers, a selector Meta renamed would still compile - so the bump also runs dotnet run scripts/facebook.cs -- check-selectors, which verifies every [Export] in ApiDefinitions.cs against the new headers and fails the build step when one is gone. Only then does Claude Code repair the definitions, and the PR opens as a draft either way.

Secrets: BUMP_BOT_APP_ID / BUMP_BOT_APP_PRIVATE_KEY (the bot that pushes and opens PRs) and CLAUDE_CODE_OAUTH_TOKEN (from claude setup-token; without it a broken binding simply lands as a draft PR with the build log attached).

Merging and publishing the binding, and moving the wrapper onto it, are separate steps.

Contributions

Feel free to create an issue or pull request. In case you would like to do massive changes in the package please firstly discuss them in the issue because otherwise there is high chance that such big PR would be rejected.

License

This repository is licensed with the MIT license.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-android36.0 is compatible.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-ios26.0 is compatible.  net10.0-maccatalyst was computed.  net10.0-maccatalyst26.0 is compatible.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed.  net10.0-windows10.0.19041 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 128 9/2/2026

Initial release: Initialize, AnonymousId, UserId, LogEvent, LogPurchase, Flush and the auto-log / advertiser-id / advertiser-tracking toggles, over Facebook Android SDK 18.3.0 and iOS SDK 18.1.1