Ilian Felinto
Ilian Felinto

Reputation: 83

Firebase Realtime Database REST API returns Unauthorized, even with token

I'm writting a Blazor Server app that connects to Firebase Realtime Database. I'm using the FirebaseDatabase SDK but need to perform a set of Atomic operations updating multiple Paths. Since the SDK do not have a method for that, I've decided to use REST API.

I'm already able to Authenticate using email/pass, which gives me access to currentUser.GetIdTokenAsync();

I'm able to read/write data on single Put/Patch operations.

But, when I try to update a path using the REST API, it fails saying: "Unauthorized".

In order to test this, I've written a simple code, below:

public async Task singleUpdate(string idPropriedade, string idLote, string novoNome)
{
    // Firebase database URL
    string firebaseUrl = DatabaseProjectSettings.projectURL;

    // Define the updates for each path
    string jsonContent = 
        "{" +
            "\"lotes\": {" +
                "\"" + idPropriedade + "\": {" +
                    "\"" + idLote + "\": {" +
                        "\"nomePropriedade\": \"" + novoNome + "\"" +
                    "}" +
                "}" +
            "}" +
        "}";


    var token = await _currUser.GetIdTokenAsync(true);


    // Create HttpClient instance
    using (HttpClient client = new HttpClient())
    {
        // Configure the request
        HttpRequestMessage request = new HttpRequestMessage
        {
            Method = HttpMethod.Put,
            RequestUri = new Uri($"{firebaseUrl}.json"),
            Content = new StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json")
        };
        request.Headers.Add("Authorization", $"Bearer {token}");

        // Send the request and get the response
        HttpResponseMessage response = await client.SendAsync(request);

        // Check if the request was successful
        if (response.IsSuccessStatusCode)
        {
            Console.WriteLine("Paths updated successfully.");
        }
        else
        {
            Console.WriteLine($"Failed to update paths. Status code: {response.StatusCode}");
        }
    }
}

If I remove the database rules, the write operation works fine. If I leave the database rules, I get the "Unauthorized" message.

I have already tested to use the token on the URL as follow, using both "auth" or "access_token": RequestUri = new Uri($"{firebaseUrl}.json?access_token={token}"), without success!

This is the response in VStudio:

enter image description here

Please send me your insights! Thanks!

Upvotes: 0

Views: 215

Answers (3)

Keith M
Keith M

Reputation: 51

The added screenshot was very helpful, it looks like your request URL looks wrong. You're missing a path after the firebaseUrl variable -- you only have a /.json after the API URL.

From the screenshot, your URL looks like:

https://[PROJECT_ID].firebaseio.com/.json

It should have at least one path element, so if you're trying to put data under lotes:

https://[PROJECT_ID].firebaseio.com/lotes.json

You may also want to change your jsonContent to remove the outer lotes

https://firebase.google.com/docs/reference/rest/database

Upvotes: 0

Keith M
Keith M

Reputation: 51

If I remove the database rules, the write operation works fine. If I leave the database rules, I get the "Unauthorized" message.

The SDK runs under a service account that probably has full read/write access. When going thru the API, then make sure that your currentUser matches an allow update and/or allow create rule in your Firestore rules for the paths/documents you're trying to write to.

https://firebase.google.com/docs/firestore/security/get-started

Upvotes: 0

Frank van Puffelen
Frank van Puffelen

Reputation: 599101

As shown in the docs on authenticating with an ID token, you need to pass that token in an auth parameter in the URL.

The Authorization header and access_token parameter are only used to authenticate with an OAuth2 access token.

Upvotes: 0

Related Questions