Delphi Firebase Realtime Database 2019/08/11

Delphi で Firebase Realtime Database のデータを変更、取得するサンプルです。
もう少しスマートな方法があるのだと思いますが、とりあえず公開しておきまます。
Indy コンポーネントを使っているので、Android、iOS でも使えるのではないかと思います。

Firebase Realtime Database について参考にしたサイト:
 Firebase Realtime Database のデータ保存、取得、ストリーミング受信実験( ESP32 , M5Stack )
 丁寧に書かれていて、非常に分かりやすいです。


■開発画面

 Indy IdHTTP と IdSSLIOHandlerSocketOpenSSL、2つのコンポーネントを使用しています。



■データベースの構造

 FireBase データ構造は下記のようになっています。(手動で作成しておきます)
 command の内容を Delphi から変更。
 Wi-Fi エリア内の ESP32 マイコンでその内容を受け取り、出力状態を変更します。
 また、response には、ESP32 から 30 秒周期で計測値を格納。・・・のように使う予定です。




■Delphi からデータを変更
 [PATCH] ボタンをクリックすると、 command の値が、"RT1ON" に変更されます。
 {"command":"RY1ON"} は、FireBaseからの返信文字列で、正常に変更されたことが分かります。


 
Database 上で確認すると、"RY1ON"に変更されていることが分かります。



■ Delphi で取得
 [GET] ボタンをクリックすると、データが取得されます。
 {"command":"RY1ON","response":"1111"} がその内容です。



// Delphi 10.3.1 Community Edition
unit tryFirebase;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdIOHandler, IdIOHandlerStream,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,
  Vcl.StdCtrls, IdServerIOHandler, IdSSL, IdSSLOpenSSL, IdIOHandlerSocket,
  IdIOHandlerStack;

type
  TForm4 = class(TForm)
    IdHTTP1: TIdHTTP;
    Button1: TButton;
    Memo1: TMemo;
    IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form4: TForm4;
const
  // Database secrets ( データベースシークレット)
  Db_auth = 'xxxxxxxxyyyyyyyyyyzzzzzzzz';
  // データベースのURL
  Db_url = 'https://xxxxxxxx.firebaseio.com';
  // データベース名?(先頭に'/'が必要)
  Db_userpath = '/esp32';

implementation

{$R *.dfm}

// データ変更
procedure TForm4.Button1Click(Sender: TObject);
var
  JsonString1, JsonString2 : string;
  JsonToSend : TStringStream;
  res : string;
begin
  Memo1.Lines.Clear;

  // 2つを書き換え
  jsonString1 := '{' +
                    '"command" : "1234",' +
                    '"response" : "5678"' +
                 '}';
  // 1つだけを書き換え
  jsonString2 := '{' +
                    '"command" : "RY1ON"' +
                 '}';
  // 1つだけ書き換えてみる
  JsonToSend := TStringStream.Create(jsonString2, TEncoding.UTF8);
  try
    // データを書き換え
    res := IdHTTP1.Patch(Db_url + Db_userpath + '.json?' + 'auth=' + Db_auth
      , JsonToSend);
    res := res.Replace(#10, '');
  except
    on E: EIdHTTPProtocolException do
      res := e.ErrorMessage;
  end;
  Memo1.Lines.Insert(0, res);
end;

// データ取得
procedure TForm4.Button2Click(Sender: TObject);
var
  JsonToReceive : TStringStream;
  res : string;
begin
  Memo1.Lines.Clear;

  JsonToReceive := TStringStream.Create('', TEncoding.UTF8);
  try
    IdHttp1.Get(Db_url + Db_userpath + '.json?' + 'auth=' + Db_auth
      , JsonToReceive);

    res := StringOf(JsonToReceive.Bytes);
    res := res.Replace(#10, '');
  except
    on E: EIdHTTPProtocolException do
      res := e.ErrorMessage;
  end;
  Memo1.Lines.Insert(0, res);

end;

procedure TForm4.FormCreate(Sender: TObject);
begin
  // オブジェクトインスペクタで設定するので、コメントアウト
  // IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
  // IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvSSLv23;
end;

end.