Sitemap
Softacom

Softacom

Your Software Migration and Modernization Partner

Use of Firebase API for adding, reading, and deleting data in a document-oriented Firebase Realtime Database via a Delphi FMX App

12 min readJan 31, 2024

--

Press enter or click to view image in full size
Use of Firebase API for adding, reading, and deleting data in a document-oriented Firebase Realtime Database via a Delphi FMX App

Currently, the use of a remote database for storing various types of data (such as product and user information for an online store, patient details in a clinic, etc.) is highly relevant.

For this purpose, both traditional relational databases and document-oriented databases can be employed. Document-oriented databases are more flexible as they provide users with a REST API for interaction.

Therefore, for data manipulation, it is necessary to use such requests as PUT, POST, GET, DELETE. They allow users to write, receive, and delete data. In contrast to relational databases, there is no need for additional drivers here. This significantly simplifies the development of software that should utilize a remote database. Data in such a database is represented in the JSON format.

In this article, we will demonstrate how to write, read, and delete data in a document-oriented Firebase Realtime Database using the Firebase API with an Embarcadero Delphi FMX application.

To work with the Firebase Realtime Database, we will use Firebase API.

Press enter or click to view image in full size

To leverage the capabilities of the document-oriented Firebase Realtime database, it is necessary to create a Firebase project.

The process of creating a new Firebase project is explained in an article dedicated to user registration and authentication using the Firebase API.

In the existing project MyNewSoftacomProj, let’s select the Realtime Database tab.

Press enter or click to view image in full size

Now let’s click on Create Database

Press enter or click to view image in full size

Then, we will need to choose the location for our database. Let’s leave as it is and we will have the United States. Now, let’s click on Next.

Press enter or click to view image in full size

Now you need to choose either the locked mode (Start in locked mode) or the test mode (Start in test mode). In the test mode, the database will be available for 30 days. To ensure better security, it is recommended to choose the locked mode (in this mode, a secret key will be used to access the data).

Press enter or click to view image in full size

The Firebase Realtime Database has been created. You need to use a URL to access the database.

Press enter or click to view image in full size

To access the database in the secure mode, it is necessary to use a secret key. We should copy and save it for future access to the database from our Embarcadero Delphi FMX application. To do this, go to Project Settings.

Press enter or click to view image in full size

Now let’s open the Service accounts tab.

Press enter or click to view image in full size

Now let’s click on Database secrets.

Press enter or click to view image in full size

Here we can find our secret code. To view it we need to click on Show.

Press enter or click to view image in full size

Now we should click on Copy and save our secret code for its further use in our Embarcadero Delphi FMX app.

Press enter or click to view image in full size

Description of the capabilities of the developed class TFirebaseHelper to save, read, and delete records in a document-oriented Firebase Realtime Database

As an example, we will be saving information about people (their names, surnames, professions) and retrieving this information from the Firebase Realtime Database. We will also implement the option to delete records from the database in our Delphi FMX application using the API.

For ease of working with the Firebase Realtime Database API, we have developed a special class called TFirebaseHelper.

Press enter or click to view image in full size

This class contains a constructor that takes an object of the TNetHttpClient class and string constant DatabaseURL and SecretKey as parameters. These constants hold the URL of the database and the secret key of the database for accessing it in the secure mode.

Press enter or click to view image in full size

The FormatJSON function allows formatting the response received from the Firebase Realtime Database and presenting it to the user in a convenient and readable form. Realtime Database and presenting it to the user in a convenient and readable form.

Press enter or click to view image in full size

The Put method takes an object Data of the TJsonObject class, which includes the necessary data to be added to the database (in our example, this is a name, surname, profession). In the Data object, parameters are stored in the “key-value” format.

The second input parameter is a string constant Path, which contains the path and name of the record being saved in the database. The parameters that should be written to the database (the Data object) are transmitted to the MultiPartFormData object (of the TMultiPartFormData class) with further adding to the database via a PUT request (using FNetHttpClient).

FNetHttpClient takes a string constant DatabaseURL as a parameter, which contains the URL of the Firebase Realtime Database.

In addition to DatabaseURL, another string constant Path is transmitted as well. It contains the path to the record and its name.

Moreover, FNetHttpClient accepts MultiPartFormData. After executing the PUT request, the JSON response from the server is stored in the ResponseContent of the TStringStream class.

Get Softacom’s stories in your inbox

Join Medium for free to get updates from this writer.

The TFirebaseHelper class allows working with the database in the secure mode. Therefore, we will also pass the secret key (auth=SecretKey). The Put method also returns the JSON response from the Firebase Realtime Database as a string with the parameters sent to the database.

Press enter or click to view image in full size

The Get method takes a string constant Path as a parameter, containing the path to the required record and its name. FNetHttpClient performs a GET request to retrieve data from the Firebase Realtime Database. The Get method returns a JSON response from the Firebase Realtime Database as a string, which contains the records obtained from the database.

Press enter or click to view image in full size

The Delete method also takes a string constant Path as a parameter. It contains the path to the required record and its name for its further deletion from the Firebase Realtime Database. FNetHttpClient performs a DELETE request to remove the data from the Firebase Realtime Database.

Press enter or click to view image in full size

Below you can find the source code of the TFirebaseHelper class.

unit FirebaseHelperClass;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes,
System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics,
FMX.Dialogs, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo, FMX.StdCtrls,
FMX.Controls.Presentation, System.Net.URLClient, System.Net.HttpClient,
System.Net.HttpClientComponent, JSON, System.Threading,
System.Net.Mime, System.Generics.Collections;
type
IFirebaseHelper = interface
function Put(const Data: TJsonObject; Path: string): string;
function Get(const Path: string): string;
function Delete(const Path: string): string;
end;
TFirebaseHelper = class(TInterfacedObject, IFirebaseHelper)
private
FNetHttpClient: TNetHTTPClient;
FSecretKey: string;
FDatabaseURL: string;
function FormatJSON(const JSON: string): string;
public
constructor Create(const NetHttpClient: TNetHTTPClient; const DatabaseURL: string;
const SecretKey: string);
function Put(const Data:TJsonObject; Path: string): string;
function Get(const Path: string): string;
function Delete(const Path: string): string;
end;
implementation
{ TFirebaseHelper }
constructor TFirebaseHelper.Create(const NetHttpClient: TNetHTTPClient;
const DatabaseURL: string; const SecretKey: string);
begin
FNetHttpClient := NetHttpClient;
if SecretKey <> '' then
FSecretKey := SecretKey
else
begin
ShowMessage('Secret key is empty!');
Exit;
end;
if DatabaseURL <> '' then
FDatabaseURL := DatabaseURL
else
begin
ShowMessage('Database URL is empty!');
Exit;
end;
end;
function TFirebaseHelper.Delete(const Path: string): string;
var
ResponseContent: TStringStream;
begin
ResponseContent := nil;
try
ResponseContent := TStringStream.Create;
FNetHttpClient.Delete(FDatabaseURL + Path + '.json?auth=' + FSecretKey, ResponseContent);
Result := FormatJSON(ResponseContent.DataString);
finally
ResponseContent.Free;
end;
end;
function TFirebaseHelper.FormatJSON(const JSON: string): string;
var
JsonValue: TJsonValue;
JsonObject: TJsonObject;
begin
JsonValue := TJsonObject.ParseJSONValue(JSON);
try
if JsonValue is TJSONNull then
Result := JSON
else
begin
JsonObject := TJsonObject(JsonValue) as TJsonObject;
Result := JsonObject.Format();
end;
finally
JsonValue.Free;
end;
end;
function TFirebaseHelper.Get(const Path: string): string;
var
ResponseContent: TStringStream;
begin
ResponseContent := nil;
try
ResponseContent := TStringStream.Create;
FNetHttpClient.Get(FDatabaseURL + Path + '.json?auth=' + FSecretKey, ResponseContent);
Result := FormatJSON(ResponseContent.DataString);
finally
ResponseContent.Free;
end;
end;
function TFirebaseHelper.Put(const Data: TJsonObject; Path: string): string;
var
MultipartFormData: TMultipartFormData;
Stream, ResponseContent: TStringStream;
begin
Stream := nil;
ResponseContent := nil;
MultipartFormData := nil;
try
MultipartFormData := TMultipartFormData.Create;
Stream := TStringStream.Create(FormatJSON(Data.ToJSON), TEncoding.UTF8);
MultipartFormData.Stream.LoadFromStream(Stream);
ResponseContent := TStringStream.Create;
FNetHttpClient.Put(FDatabaseURL + Path + '.json?auth=' + FSecretKey,
MultipartFormData, ResponseContent);
Result := FormatJSON(ResponseContent.DataString);
finally
Stream.Free;
ResponseContent.Free;
MultipartFormData.Free;
end;
end;
end.

The implementation of features for adding, reading, and deleting records from the Firebase Realtime Database in our FMX Delphi application

To interact with the Firebase Realtime Database API (to send PUT, GET, DELETE requests to the database in our Delphi FMX application), the TNetHttpClient component is used.

Press enter or click to view image in full size

In our application, we will transmit three parameters to the database: a name, surname, and profession. We will use TEdit components for entering these parameters.

Press enter or click to view image in full size

Our application allows writing data to the database. It also enables retrieving all data from the database or a specific record based on the surname. There is also the possibility to delete a specific record using the surname. All these functions are implemented as handlers for corresponding buttons (of the TButton class).

Press enter or click to view image in full size

The JSON response from the Firebase Realtime Database is displayed with the help of the TMemo component.

Press enter or click to view image in full size

We will declare two fields, FSecretKey and FDatabaseURL (the string type), which store the URL of the database and the secret key.

Press enter or click to view image in full size

In the OnCreate method of the main form (MainForm), we will connect the URL of the database and the secret code.

Press enter or click to view image in full size

Let’s consider the implementation of a button handler that performs the writing of parameters to the database (PUT to DB). To carry out this task, we will declare a FirebaseObject object (of the IFirebaseHelper type). Also, for storing data with its further saving to the database, we will declare a JsonToDB object (of the TJSONObject type). For storing the JSON response from the service, we will declare a string variable AnswerFromFirebase.

Press enter or click to view image in full size

Next, it is necessary to call the constructor of the TFirebaseHelper class and pass our NetHttpClient1 object (of the TNetHttpClient class) along with the values of the FDatabaseURL and FSecretKey fields.

Press enter or click to view image in full size

We will add parameters such as a name, surname, and profession to the JsonToDB object (parameters are stored in the “key-value” format) with their further saving to the database. We will read the parameter values from the corresponding TEdit input fields (EditName, EditSurname, EditProfession). If necessary, you can send an unlimited number of values using the AddPair method. In our example, we used three parameters (Name, Surname, Profession).

Press enter or click to view image in full size

Next, we will make a PUT request to add our parameters to the database. For this, we will use the Put method of the FirebaseObject. This method takes JsonToDB as input parameters (here our transmitted parameters are stored), the path, and the name of the record (in our case, the surname). It is necessary to perform all database requests using TTask to avoid blocking the interface of our Delphi FMX application. The response from the Firebase Realtime Database is stored in the string variable AnswerFromFirebase.

Press enter or click to view image in full size

To display the JSON response from the Firebase Realtime Database, we will use TThread.Synchronize (to update the TMemo component in the main thread).

Press enter or click to view image in full size

You can see the code for the “PUT to DB” button handler below.

procedure TMainForm.btnPutClick(Sender: TObject);
var
JsonToDB : TJSONObject;
FirebaseObject: IFirebaseHelper;
AnswerFromFirebase: string;
begin
Memo1.Lines.Clear;
FirebaseObject := TFirebaseHelper.Create(NetHttpClient1, FDatabaseURL, FSecretKey);
TTask.Run(procedure
begin
JsonToDB := TJSONObject.Create;
try
JsonToDB.AddPair('Name', EditName.Text);
JsonToDB.AddPair('Surname', EditSurname.Text);
JsonToDB.AddPair('Profession', EditProfession.Text);
AnswerFromFirebase := FirebaseObject.Put(JsonToDB, 'MyNewData/' + EditSurname.Text);
TThread.Synchronize(nil,
procedure
begin
Memo1.Text := AnswerFromFirebase;
TabControl1.GotoVisibleTab(1);
end);
finally
JsonToDB.Free;
end;
end);
end;

Let’s demonstrate the capability of our Delphi FMX application to save records to the database using the PUT method. We will show the work of the application on the Windows platform.

Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size

Let’s consider the implementation of a button handler that reads records from the database (Get All from DB). To read all records from the database using the indicated path, we will apply the Get method of the TFirebaseHelper class. We will display the obtained values of the records in the form of a JSON response from the Firebase Realtime Database using the TMemo component.

Press enter or click to view image in full size

The code of the Get All from DB button handler looks the following way.

procedure TMainForm.btnGetAllClick(Sender: TObject);
var
JsonResponse: string;
FirebaseObject: IFirebaseHelper;
begin
Memo1.Lines.Clear;
FirebaseObject := TFirebaseHelper.Create(NetHttpClient1, FDatabaseURL, FSecretKey);
TTask.Run(
procedure
begin
JsonResponse := FirebaseObject.Get('MyNewData/');
TThread.Synchronize(nil,
procedure
begin
Memo1.Lines.Add(JsonResponse);
TabControl1.GotoVisibleTab(1);
end);
end);

Let’s demonstrate the process of reading data from the database in our Delphi FMX application.

Press enter or click to view image in full size

Our Delphi FMX application also allows reading data from the database based on the surname. For this purpose, a similar method Get is used. We will transmit the path to the record and the name of the record (surname).

Press enter or click to view image in full size

You can see the code of the Get from DB by Surname button handler below.

procedure TMainForm.btnGetBySurnameClick(Sender: TObject);
var
JsonResponse: string;
FirebaseObject: IFirebaseHelper;
begin
Memo1.Lines.Clear;
FirebaseObject := TFirebaseHelper.Create(NetHttpClient1, FDatabaseURL, FSecretKey);
TTask.Run(
procedure
begin
JsonResponse := FirebaseObject.Get('MyNewData/' + EditSurname.Text);
TThread.Synchronize(nil,
procedure
begin
Memo1.Lines.Add(JsonResponse);
TabControl1.GotoVisibleTab(1);
end);
end);
end;

Let’s demonstrate reading data from the database in our Delphi FMX application based on the surname.

Press enter or click to view image in full size

To delete records from the database in our Delphi FMX application, it is necessary to use the Delete method of the TFirebaseHelper class. As a parameter, we will transmit the path to the record and the surname of the person in the database whose record we want to delete.

We will display the deletion result to the user with the help of the TMemo component.

Press enter or click to view image in full size

The code for the Delete from DB button handler is provided below.

procedure TMainForm.btnDeleteClick(Sender: TObject);
var
FirebaseObject: IFirebaseHelper;
ResponseFromFirebase: string;
begin
Memo1.Lines.Clear;
FirebaseObject := TFirebaseHelper.Create(NetHttpClient1, FDatabaseURL, FSecretKey);
TTask.Run(
procedure
begin
try
ResponseFromFirebase := FirebaseObject.Delete('MyNewData/' + EditSurname.Text);
finally
TThread.Synchronize(nil,
procedure
begin
if ResponseFromFireBase = '' then
Memo1.Text := 'Record ' + EditSurname.Text + ' deleted!';
TabControl1.GotoVisibleTab(1);
end);
end;
end);
end;

Let’s demonstrate the process of deleting data from the database in our Delphi FMX application based on the surname.

Press enter or click to view image in full size
Press enter or click to view image in full size

Let’s demonstrate the work of the application on the Android and MacOS platforms.

Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size

--

--

Written by Softacom

Your Software Migration and Modernization Partner