Delphi - Google Firebase - HTTP

Delphi - Google Firebase - HTTP

我正在尝试通过 HTTP 在 Firebase 上发送一个 POST 请求,无论是在代码中还是在 REST 调试器中,但是 returns 一个错误:

HTTP/1.1 401 The request was missing an Authentification Key (FCM Token). Please, refer to section "Authentification" of the FCM documentation, at https=//firebase.google.com/docs

使用 Chrome 的 Postman 扩展,它可以工作。

这是代码:

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  IdHTTP, IdIOHandler, IdIOHandlerStream,
  IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdSSLOpenSSLHeaders_Static,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.ScrollBox, FMX.Memo,
  IdGlobal, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdServerIOHandler, IdCoderMIME;
begin
  try
    IdIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    IdIOHandler.ReadTimeout := IdTimeoutInfinite;
    IdIOHandler.ConnectTimeout := IdTimeoutInfinite;
    IdHTTP := TIdHTTP.Create(nil);
    try
      idHttp.Request.Clear;
      idHttp.Request.CustomHeaders.Clear;
      idHttp.Request.ContentType := 'application/json';
      idhttp.Request.Charset := 'UTF-8';
      IdHTTP.IOHandler := IdIOHandler;
      IdHTTP.ReadTimeout := IdTimeoutInfinite;
      IdHTTP.Request.Connection := 'Keep-Alive';
      IdIOHandler.SSLOptions.Method := sslvSSLv23;
      IdHTTP.Request.Method := 'POST';
      IdHTTP.Request.CustomHeaders.Values['Authorization:key'] := 'AAAAYsnMbsY:APA91bEjYZK-xxxxxxx......';
      jsonString := '{"to" : "APA91bFJSdGW_yrX7p_TNKZ4k0OpdXTQM6xdd7BUsslk6zSvZlBmoAnfvyX-nBm4DYY-xxxxx......",' +
                    '"data" : {' +
                    '"Nick" : "Teste de Push",' +
                    '"body" : "Corpo do push",' +
                    '"Room" : "Apenas um teste"' +
                    '},}';
      JsonToSend := TStringStream.Create(jsonString);
      try
        response := IdHTTP.Post('https://fcm.googleapis.com/fcm/send', JsonToSend);
        response := response.Replace(Char(#10), '');
      except
        on E:EIdHTTPProtocolException do
        memo1.Lines.Insert(0, e.ErrorMessage);
      end;
      memo1.Lines.Insert(0, response);
    finally
      IdHTTP.Free;
    end;
  finally
    IdIOHandler.Free;
  end;
end;

您的 Delphi 代码未正确分配 Authentication 请求 header。你需要改变这个:

IdHTTP.Request.CustomHeaders.Values['Authorization:key'] := 'AAAAYsnMbsY:APA91bEjYZK-xxxxxxx......';

改为:

IdHTTP.Request.CustomHeaders.Values['Authorization'] := 'key=AAAAYsnMbsY:APA91bEjYZK-xxxxxxx......';

您也应该将 IdHTTP.Request.BasicAuthentication 属性 设置为 false。

除此之外,由于您将 Request.Charset 属性 设置为 UTF-8,因此您应该构造 TStringStream 以匹配:

JsonToSend := TStringStream.Create(jsonString, TEncoding.UTF8);

话虽如此,请尝试以下代码:

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.ScrollBox, FMX.Memo,
  IdGlobal, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdHTTP, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL
  {$IFDEF IOS}
  , IdSSLOpenSSLHeaders_Static
  {$ENDIF}
  ;

...

begin
  IdHTTP := TIdHTTP.Create(nil);
  try
    IdIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
    IdIOHandler.SSLOptions.Method := sslvSSLv23;
    IdHTTP.IOHandler := IdIOHandler;

    IdHTTP.Request.ContentType := 'application/json';
    IdHTTP.Request.Charset := 'UTF-8';
    IdHTTP.Request.CustomHeaders.Values['Authorization'] := 'key=AAAAYsnMbsY:APA91bEjYZK-xxxxxxx......';

    jsonString := '{"to" : "APA91bFJSdGW_yrX7p_TNKZ4k0OpdXTQM6xdd7BUsslk6zSvZlBmoAnfvyX-nBm4DYY-xxxxx......",' +
                   '"data" : {' +
                   '"Nick" : "Teste de Push",' +
                   '"body" : "Corpo do push",' +
                   '"Room" : "Apenas um teste"' +
                   '},}';
    JsonToSend := TStringStream.Create(jsonString, TEncoding.UTF8);
    try
      response := IdHTTP.Post('https://fcm.googleapis.com/fcm/send', JsonToSend);
      response := response.Replace(#10, '');
    except
      on E: EIdHTTPProtocolException do
        response := e.ErrorMessage;
    end;
    Memo1.Lines.Insert(0, response);
  finally
    IdHTTP.Free;
  end;
end;