Pinqponq.Push.Fcm 1.1.0

Prefix Reserved
dotnet add package Pinqponq.Push.Fcm --version 1.1.0
                    
NuGet\Install-Package Pinqponq.Push.Fcm -Version 1.1.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="Pinqponq.Push.Fcm" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Pinqponq.Push.Fcm" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Pinqponq.Push.Fcm" />
                    
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 Pinqponq.Push.Fcm --version 1.1.0
                    
#r "nuget: Pinqponq.Push.Fcm, 1.1.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 Pinqponq.Push.Fcm@1.1.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=Pinqponq.Push.Fcm&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Pinqponq.Push.Fcm&version=1.1.0
                    
Install as a Cake Tool

Pinqponq.Push.Fcm

Firebase Cloud Messaging (FCM) sender for backends that push to mobile apps. You give it a Firebase service account, and it gives you an IFcmSender that sends notifications and data-only pushes to device tokens, sends to topics and manages topic subscriptions. Every send to tokens returns one result per token that says whether the token is invalid (delete it) or the push provider credentials are broken (fix them, every push to that platform fails).

The client side is in deveng-core-kmp (pinqponq/deveng-core-kmp#116): it registers the device with FCM and hands the token to your backend.

Install

dotnet add package Pinqponq.Push.Fcm

Requirements

  • .NET 8.0, 9.0, or 10.0
  • A Firebase service account JSON (Firebase console → Project settings → Service accounts)
  • An ILogService registration, for example from Pinqponq.Observability

Quick start

{
  "Fcm": {
    "CredentialPath": "firebase-service-account.json"
  }
}
builder.Services.AddPinqponqObservability(/* … */);
builder.Services.AddPinqponqFcm(builder.Configuration.GetSection(FcmOptions.SectionName));
public sealed class ReminderNotifier(IFcmSender fcmSender)
{
    public Task<IReadOnlyList<FcmSendResult>> Notify(IReadOnlyCollection<string> deviceTokens) =>
        fcmSender.SendToTokens(
            new FcmMessage { Title = "Reminder", Body = "Your session starts in 10 minutes" },
            deviceTokens);
}

The service account JSON is a secret: keep the file out of the repository, or read the JSON from Vault (Pinqponq.Configuration.Vault) into Fcm:CredentialJson.

Options

Option Default Meaning
IsEnabled true false sends nothing and needs no credential (developer machines).
CredentialPath — Service account JSON file. A relative path is resolved against the app directory.
CredentialJson — The service account JSON itself. Set this or CredentialPath, not both.
DataOnlyAndroidPriority Normal Android priority of SendDataOnlyToTokens. High wakes the device at once. Use it only when the app shows a notification for every such push, or Android lowers the app's priority.
IsSendFailureLoggingEnabled true false turns off the fcm_send_partial_failure and fcm_provider_credential_invalid log records. Use it when your application logs the returned results itself, so each failure is logged once. Topic log records stay on.

The options are validated at startup: when IsEnabled is true, exactly one credential must be set, the file must exist and the JSON must be a service account.

Sending

Method Sends
SendToTokens(message, tokens) A notification (title, body, optional image and data) to device tokens.
SendDataOnlyToTokens(data, tokens) Data without a notification block. The app decides what to show.
SendToTopic(topic, message) A notification to every device subscribed to the topic.
SubscribeToTopic(tokens, topic) / UnsubscribeFromTopic(tokens, topic) Topic membership. Rejected tokens are logged.
  • More than 500 tokens are split into several FCM calls (1,000 for topic changes), so you can pass any number.
  • No tokens, or IsEnabled set to false, sends nothing and returns an empty list.
  • FcmMessage.Android and FcmMessage.Apns take FirebaseAdmin's AndroidConfig and ApnsConfig as they are. The package sets nothing there by default: no sound, badge or content-available.

Results and invalid tokens

SendToTokens and SendDataOnlyToTokens return an FcmSendResult per token, in the order the tokens were given:

Field Meaning
IsSuccess FCM accepted the push. Acceptance is not proof of delivery.
ErrorCode / ErrorMessage FCM's error code (Unregistered, ThirdPartyAuthError, …), or the general Firebase code when the request failed below the messaging layer.
IsTokenInvalid FCM answered Unregistered: the token will never work again.
IsProviderCredentialInvalid FCM answered ThirdPartyAuthError: the APNs key (or another provider credential) is invalid. Not the token's fault.

InvalidArgument and SenderIdMismatch are not treated as invalid tokens: a bad payload or the wrong Firebase project gives the same answer for every token, and deleting them all would be wrong. They come back as failures with their ErrorCode.

To delete invalid tokens, implement IFcmInvalidTokenHandler and register it. The sender calls it after each send with the tokens FCM reported as Unregistered:

public sealed class DeviceTokenCleaner(AppDbContext dbContext) : IFcmInvalidTokenHandler
{
    public Task HandleInvalidTokens(IReadOnlyList<string> invalidTokens, CancellationToken cancellationToken = default) =>
        dbContext.Devices.Where(device => invalidTokens.Contains(device.PushToken)).ExecuteDeleteAsync(cancellationToken);
}

builder.Services.AddScoped<IFcmInvalidTokenHandler, DeviceTokenCleaner>();

Logging

Failures are written through ILogService with the event names in FcmLogEvents. Tokens are credentials, so a record holds only the last 6 characters of each token.

Event Level When
fcm_send_partial_failure Warning Some tokens of a send failed. Off when IsSendFailureLoggingEnabled is false.
fcm_provider_credential_invalid Error A send failed with ThirdPartyAuthError. Off when IsSendFailureLoggingEnabled is false.
fcm_topic_subscribe_partial_failure / fcm_topic_unsubscribe_partial_failure Warning FCM rejected tokens of a topic change. Each failure has FCM's reason.
fcm_disabled Debug IsEnabled is false and a send was skipped.

Firebase app

The package creates its own named Firebase app (Pinqponq.Push.Fcm) on the first send and reuses it afterwards. A default Firebase app your application creates for something else is left alone.

What stays in your application

Device token storage, notification texts and their translations, topic names and segments, user preferences, scheduling, and platform-specific pushes such as APNs widget updates.

Repository

https://github.com/pinqponq/pinqnuqets

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
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.1.0 97 10/18/2026
1.0.0 88 10/18/2026