Firebase Cloud Messaging (FCM) with .NET

For one of my .NET projects I needed a simple way to send Push Messages with Firebase Cloud Messaging (FCM), so I wrote FcmSharp:

FcmSharp implements the entire Firebase Cloud Messaging HTTP Protocol and supports:

  • Downstream HTTP Messages
  • Notification Payloads
  • Topic Messages
  • Device Group Messages

FcmSharp supports .NET Core as of Version 1.0.0.

Installing FcmSharp

You can use NuGet to install FcmSharp. Run the following command in the Package Manager Console.

PM> Install-Package FcmSharp

Quickstart

The Quickstart shows you how to work with FcmSharp in C#.

// Copyright (c) Philipp Wagner. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Threading;
using FcmSharp.Model.Options;
using FcmSharp.Model.Topics;
using FcmSharp.Requests.Topics;
using FcmSharp.Settings;

namespace FcmSharp.Console
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            // Read the API Key from a File, which is not under Version Control:
            var settings = new FileBasedFcmClientSettings("/Users/bytefish/api.key");

            // Construct the Client:
            using (var client = new FcmClient(settings))
            {
                // Construct the Data Payload to send:
                var data = new
                {
                    A = new
                    {
                        a = 1,
                        b = 2
                    },
                    B = 2,
                };

                // Options for the Message:
                var options = FcmMessageOptions.Builder()
                    .setTimeToLive(TimeSpan.FromDays(1))
                    .Build();

                // The Message should be sent to the News Topic:
                var message = new TopicUnicastMessage<dynamic>(options, new Topic("news"), data);

                // Finally send the Message and wait for the Result:
                CancellationTokenSource cts = new CancellationTokenSource();

                // Send the Message and wait synchronously:
                var result = client.SendAsync(message, cts.Token).GetAwaiter().GetResult();

                // Print the Result to the Console:
                System.Console.WriteLine("Result = {0}", result);
            }
        }
    }
}

How to Configure a Proxy

FcmSharp uses the HttpClient for making requests to the Firebase Cloud Messaging server. So in order to configure a proxy for the HTTP requests, you can configure the HttpClient used in FcmSharp. This is done by instantiating the FcmHttpClient with a configured HttpClient.

The following test shows how to build the FcmClient with a custom FcmHttpClient.

/// <summary>
/// The WebProxy.
/// </summary>
public class WebProxy : IWebProxy
{
    public Uri ProxyUri { get; set; }

    public ICredentials Credentials { get; set; }

    public Uri GetProxy(Uri destination)
    {
        return ProxyUri;
    }

    public bool IsBypassed(Uri host)
    {
        return false;
    }
}

[Test, Explicit]
public void TestHttpClientWithProxy()
{
    // Settings to be used:
    IFcmClientSettings settings = new FileBasedFcmClientSettings("/Users/bytefish/api.key");

    // The Proxy Address:
    Uri proxyUri = new Uri(string.Format("{0}:{1}", "<proxy_address>", "<proxy_port>"));

    // Credentials for the Proxy:
    ICredentials proxyCredentials = new NetworkCredential(
        "<proxy_username>",
        "<proxy_password>"
    );

    // Define the Proxy:
    IWebProxy proxy = new WebProxy
    {
        ProxyUri = proxyUri,
        Credentials = proxyCredentials

    };

    // Now create a client handler with the Proxy settings:
    HttpClientHandler httpClientHandler = new HttpClientHandler()
    {
        Proxy = proxy,
        PreAuthenticate = true,
        UseDefaultCredentials = false,
    };

    // Build the Custom FcmHttpClient:
    FcmHttpClient fcmHttpClient = new FcmHttpClient(settings, new HttpClient(httpClientHandler), JsonSerializer.Default);

    // Build the HttpClient:

    using (var client = new FcmClient(settings, fcmHttpClient))
    {
        CancellationTokenSource cts = new CancellationTokenSource();

        // Build the message:
        var message = new TopicUnicastMessage<int>(new FcmMessageOptionsBuilder().Build(), new Topic("a"), 1);

        // And send the message:
        var result = client.SendAsync(message, cts.Token).GetAwaiter().GetResult();
    }
}

How to do Synchronous API Calls

The FcmClient only provides an asynchronous API, and a Synchronous API won't be added. I know that asynchronous programming can be very challenging for beginners, so here is how you can turn an async call into a synchronous one:

var result = client.SendAsync(message, cts.Token).GetAwaiter().GetResult();
comments powered by Disqus