question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Firebase Cloud Messaging (FCM) Access Token Issue

See original GitHub issue

For some reason the GoogleCredential does not seem to be creating an appropriate credential when accessing FCM. Looking off of the instructions at Authorize Http v1 send requests I followed the basic format of the Java example with this code:

using (var stream = new FileStream("project-firebase-adminsdk.json", FileMode.Open, FileAccess.Read))
{
    var credential = GoogleCredential.FromStream(stream).CreateScoped("https://www.googleapis.com/auth/firebase.messaging", "https://www.googleapis.com/auth/cloud-platform");
    var token = credential.UnderlyingCredential.GetAccessTokenForRequestAsync().Result;
}

The instructions on the site linked above say that I only should need the scope “https://www.googleapis.com/auth/firebase.messaging” but when I hit the endpoint with this access token it tells me that I also need to add the other scope as well which is why I did. The json credentials file (stored in project-firebase-adminsdk.json) was downloaded from the correct place in the firebase console as mentioned in the instructions so that should be correct.

The Json token that is returned isn’t one that is recognized as valid by one of the main jwt utilities in .net System.IdentityModel.Tokens.Jwt so I am imagining that the format of the token is not standard. The first time I sent something it complained about missing credentials and then didn’t after the update so I am assuming that means the api is able to make sense of the jwt even if it isn’t a standard one that System.IdentityModel.Tokens.Jwt can recognize.

Is this an error with the client library or is there some other preferred way to use this library (or maybe a different library) to access a Google Api like FCM? I can’t really do much with looking into the jwt since I can’t parse it.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:9

github_iconTop GitHub Comments

1reaction
ScottHerocommented, Jan 3, 2018

No problem, I guess then that you knew to ask that since it is probably a common user error when using Google APIs in general. I will go ahead and leave a comment on the firebase fcm documentation mentioning that not having the API enabled can cause it not to work and asking them to include something about it (unless they already do have it and I keep missing it).

Thanks so much for your help Jon! You have really been a big help since I don’t know how long it would have taken me to figure out that the API would have needed to be enabled.

1reaction
ScottHerocommented, Jan 2, 2018

Hey Jon,

No problem at all, thanks for your response! When I saw “OAuth 2.0 token” in the documentation I assumed that it meant it would be a JWT so thank you for clarifying that part. I think the scope is required since it is mentioned in the firebase documentation (under the “To retrieve an access token:” portion of the page) so it looks like the code I have is behaving as expected then by pulling back the OAuth2 token.

A more complete example of the code that I am testing with is given below:

public static async Task<int> Main(string[] args)
{
  var client = new HttpClient();
  var response = await CallFirebaseApi(client);

  return 0;
}

private static async Task<HttpResponseMessage> CallFirebaseApi(HttpClient client)
{
    var msg = new HttpRequestMessage()
    {
        Version = HttpVersion.Version11,
        Method = HttpMethod.Post,
        RequestUri = new Uri("https://fcm.googleapis.com/v1/projects/projectid/messages:send"),
        Content = new StringContent(@"{
                ""message"":{
                    ""topic"" : ""TestTopic"",
                    ""notification"" : {
                        ""body"" : ""This is an FCM notification message!"",
                        ""title"" : ""FCM Message"",
                    }
                }
            }", Encoding.UTF8, "application/json")
    };
            
    msg.Headers.Add("Authorization", "Bearer " + GetAccessToken());
    return await client.SendAsync(msg).ConfigureAwait(false);
}

private static async Task<string> GetAccessToken()
{
    using (var stream = new FileStream("projectid-firebase-adminsdk-dzaxs-0180c0317f.json", FileMode.Open, FileAccess.Read))
    {
        var credential = GoogleCredential.FromStream(stream).CreateScoped("https://www.googleapis.com/auth/firebase.messaging");
        return await credential.UnderlyingCredential.GetAccessTokenForRequestAsync().ConfigureAwait(false);
    }
}

I followed the instructions for the FCM HTTP v1 API from Authorize Send Requests and Build Send Requests. Anywhere in the code above that I have the term “projectid” it has been replaced with our actual project id as listed on the firebase console’s general settings tab.

The response back from the api is a 401 Unauthorized. There is a WWW-Authenticate line in the response which reads:

WWW-Authenticate: Bearer realm=“https://accounts.google.com/”, error=“invalid_token”

All that said, I am using C# which there are no code samples for. I tried to gauge what I should use based on the .net documentation and looking off of the Java sample (under “to retrieve an access token:”). Maybe I mixed and matched something that doesn’t belong?

As an added point of confusion for me I noticed that the Java samples are different depending on where you look (maybe they are for different purposes?). The first Java sample is from Authorize Send Requests and is as follows:

private static String getAccessToken() throws IOException {
  GoogleCredential googleCredential = GoogleCredential
      .fromStream(new FileInputStream("service-account.json"))
      .createScoped(Arrays.asList(SCOPES));
  googleCredential.refreshToken();
  return googleCredential.getAccessToken();
}

The second Java sample is from the “Settings” -> “Service Account” path in the Firebase console for our project (which is where I got the credential file ‘projectid-firebase-adminsdk-dzaxs-0180c0317f.json’ referenced in my code sample from):

FileInputStream serviceAccount =
  new FileInputStream("path/to/serviceAccountKey.json");

FirebaseOptions options = new FirebaseOptions.Builder()
  .setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
  .setDatabaseUrl("https://projectid.firebaseio.com")
  .build();

FirebaseApp.initializeApp(options);

I am not sure which one is the more correct one to be looking at.

It should also be noted that if I follow the instructions for the legacy protocol I am able to get a 200 response back so it seems to be working there.

Thank you for your time and help! If there is anything else that you want me to add or give more details on please let me know!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Best practices for FCM registration token management
Make sure to detect invalid token responses from FCM and respond by deleting from your system any registration tokens that are known to...
Read more >
FCM OAuth2.0 access token creation throwing "TypeError ...
Im trying to use JSON Web Tokens (JWTs) to mint access tokens for Firebase Cloud Messaging, but I am having difficulty applying the...
Read more >
Managing Cloud Messaging Tokens
Every time the user opens the app, you should get the token from FCM (call Firebase.messaging.token ) to ensure the device has the...
Read more >
Get access token for Firebase Cloud Messaging API (V1) ...
How I want to get Access Token for Firebase Cloud Messaging API (V1). ... futureToken.get(); final String FCM_API = "https://fcm.googleapis ...
Read more >
Get firebase token flutter. final credential = GoogleAuthPro
Getting the error getToken, error fetching instanceID: FCM token returns a null value. googleapis. Get Started With Firebase Cloud Messaging; Introduction.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found