Запрещенная ошибка Firebase 403 при попытке отправить push-уведомление

#c# #firebase #firebase-authentication #firebase-cloud-messaging #httpwebrequest

#c# #firebase #firebase-аутентификация #firebase-облако-обмен сообщениями #httpwebrequest

Вопрос:

У меня есть полностью работающий устаревший HTTP-запрос:

 HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("https://fcm.googleapis.com/fcm/send");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.PreAuthenticate = true;
httpWebRequest.Headers.Add("Authorization", "key="   key);
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
    string message = "{"to":""   token.ToString()   
        "","notification":{"body":""   body.ToString()  
        "","title":""   title.ToString()   ""},"   
        ""data":{"key":""   dataKey.ToString()   
        "","value":""   dataValue.ToString()   ""}}";

    streamWriter.Write(message);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
    name = streamReader.ReadToEnd();
}
 

Я пытаюсь перейти на последнюю версию:

 string uri = String.Format("https://fcm.googleapis.com/v1/projects/{0}/messages:send?access_token={1}amp;key={2}amp;alt=json", project, AccessToken, key);
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
httpWebRequest.Accept = "application/json";
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
    string message = "{"validateOnly":true,"  
        ""message":{"  
            ""token":""   token.ToString()   "","  
            ""notification":{"  
                ""body":""   body.ToString()   "","  
                ""image":""   image.ToString()   "","  
                ""title":""   title.ToString()   """  
                "},"data":{"  
                ""key":""   dataKey.ToString()   "","  
                ""value":""   dataValue.ToString()   """  
                "}"  
            "}"  
        "}";
    streamWriter.Write(message);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
    name = streamReader.ReadToEnd();
}
 

Но при GetResponse получении The remote server returned an error: (403) Forbidden. я ранее получал ошибку 401 (неавторизованную), но это было потому, что я не использовал правильный ключ доступа, теперь я авторизован и использую это:

 var scopes = new[] { "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/firebase.database" };

GoogleCredential credential;
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
    credential = GoogleCredential.FromStream(stream).CreateScoped(scopes);
}
AccessToken = await credential.UnderlyingCredential.GetAccessTokenForRequestAsync();
return AccessToken;
}
 

Я действительно не уверен, чего мне не хватает, у меня включены все необходимые API-интерфейсы Google Cloud для этого проекта.

Ответ №1:

(403) Forbidden означает, что вы прошли проверку подлинности (ваш токен действителен), но у вас нет авторизации для доступа к ресурсу в вашем URL .

Комментарии:

1. Большинство из нас, разработчиков, уже знают, что вы заявили, несмотря на это, это помогло мне заметить, что я нажимал промежуточный URL-адрес, используя токены производственного доступа. Спасибо.

Ответ №2:

Добавьте еще одну область в метод oauth. "https://www.googleapis.com/auth/firebase.messaging" теперь кажется прямолинейным, но для этого c # post целиком нет места. Надеюсь, это поможет кому-то еще с этим подходом.

 var scopes = new[] { "https://www.googleapis.com/auth/firebase.messaging", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/firebase.database" };

GoogleCredential credential;
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
    credential = GoogleCredential.FromStream(stream).CreateScoped(scopes);
}
AccessToken = await credential.UnderlyingCredential.GetAccessTokenForRequestAsync();