-
-
Notifications
You must be signed in to change notification settings - Fork 54
FB4D Reference IRealTimeDB
This chapter mainly only describes the synchronous method calls for the convenience of description. The asynchronous method calls are identical but with additional callback routines for success and failure.
The interface will be created by the constructor of the class TRealTimeDB in the unit FB4D.RealTimeDB. The new constructor CreateByURL expects as parameters the Firebase URL of the Realtime Database and the instance of the interface IFirebaseAuthentication that is in the state signed-in. You find your FirebaseURL in the Firebase Console in the Realtime Database/Data view in the header after the link icon.
var
Database: IRealTimeDB;
begin
Database := TRealTimeDB.CreateByURL(<FirebaseURL: string>, <IFirebaseAuthentication>);
There was a change in the Firebase console on how to create real-time databases. Previously the Firebase URL was derivable from the project ID. Therefore the former constructor TRealTimeDB.Create
is marked as deprecated and should not be used anymore.
Alternatively, you can use the class factory TFirebaseConfiguration.RealTimeDB to get an instance of IRealTimeDB.
The Get method reads a JSON node and returns it with all subnodes for a given JSON path.
For this purpose, the node path is passed in the ResourceParams
as a dynamic string array (e.g. ['Top', 'Mid', 'Low'] to build the following JSON path: '/Top/Mid/Low').
As a result, the caller receives a TJSONValue class, which can be a derived TJSONObject for a JSON node that contains more than one field or subnodes. Note that the caller has to free this TJSONValue to avoid memory leaks.
function GetSynchronous(ResourceParams: TRequestResourceParam;
QueryParams: TQueryParams = nil): TJSONValue;
The QueryParams can optionally be used to sort the result with Order-By or to limit the range of the result. The following code excerpt shows an application for using the asynchronous Get method call along with the optional arguments in QueryParams.
procedure TMyForm.GetRealTimeNodes(const TopNodeName, MidNodeName,
SortNodeName: string; NumberOfFirstRow, NumberOfLastRow: integer);
var
Query: TQueryParams;
begin
Query := TQueryParams.Create;
try
Query.AddOrderBy(SortNodeName);
Query.AddLimitToFirst(NumberOfFirstRow);
Query.AddLimitToLast(NumberOfLastRow);
fRealTimeDB.Get([TopNodeName, MidNodeName], OnGetResponse, OnGetError, Query);
finally
Query.Free;
end;
end;
procedure TMyForm.OnGetResponse(ResourceParams: TRequestResourceParam;
Val: TJSONValue); ...
procedure TMyForm.OnGetError(const RequestID, ErrMsg: string); ...
It is important that the nodes do not necessarily appear in the desired order in the resulting JSON, even with an OrderBy. In combination with LimitToFirst or LimitToLast, however, the desired nodes are always returned.
In cases where you use the same structures for a lot of data, you can use data filtering to read out only a subset of the nodes. E.g. your database contains the following tree in the top node Chat:
Chat
> -NDX92PHk-M-qf3TZUDd
--> Ind: 1
--> Msg: "First chat message"
> -Nk-Hl4_TP-wOrB4D2_4
--> Ind: 2
--> Msg: "Second chat message"
> -NwE72Wh_MQPYqlD4-1a
--> Ind: 3
--> Msg: "Third chat message"
A query built with
TQueryParams.CreateQueryParams.AddOrderByAndEqualTo('Ind', 2)
allows to retrieve just the second node:
-Nk-Hl4_TP-wOrB4D2_4: {Ind: 2, Msg: "Second chat message"}
The TQueryParams helper class offers this method for 3 different filter value types: string, integer and float.
The Put method writes or overwrites an entire JSON node with all its child nodes for a given JSON path.
function PutSynchronous(ResourceParams: TRequestResourceParam;
Data: TJSONValue; QueryParams: TQueryParams = nil): TJSONValue;
The following code excerpt shows an application for using the asynchronous Put method call.
procedure TMyForm.GetRealTimeNodes(const TopNodeName, MidNodeName,
FieldAVal, FieldBVal: string);
var
Data: TJSONObject;
begin
Data := TJSONObject.Create;
try
Data.AddPair('FieldA', FieldAVal);
Data.AddPair('FieldB', FieldBVal);
fRealTimeDB.Put([TopNodeName, MidNodeName], Data, OnPutResponse, OnPutError);
finally
Data.Free;
end;
end;
procedure TMyForm.OnPutResp(ResourceParams: TRequestResourceParam;
Val: TJSONValue); ...
procedure TMyForm.OnPutError(const RequestID, ErrMsg: string); ...
To delete an entire node in the JSON tree you must use the Delete method. In the ResourceParams pass the desired JSON path as a dynamic string array.
function DeleteSynchronous(ResourceParams: TRequestResourceParam;
QueryParams: TQueryParams = nil): boolean;
The Post method is comparable to an auto-increment index in relational databases. It creates a subnode with a unique ID.
function PostSynchronous(ResourceParams: TRequestResourceParam;
Data: TJSONValue; QueryParams: TQueryParams = nil): TJSONValue;
Note that the caller has to free this TJSONValue to avoid memory leaks.
The Put method does not allow to change the content of the value of a node that contains sub-nodes without lost of sub-nodes. For this purpose, the method Patch must be used.
function PatchSynchronous(ResourceParams: TRequestResourceParam;
Data: TJSONValue; QueryParams: TQueryParams = nil): TJSONValue;
Note that the caller has to free this TJSONValue to avoid memory leaks.
Install a listener to be notified of any changes in and under a particular JSON node. The following function starts a long-running REST call that receives a message by any data change on the registered node. This is a much better approach than polling a JSON node with repeated calls of the method Get because much less data is required to transfer between the cloud database and the client application.
function ListenForValueEvents(ResourceParams: TRequestResourceParam;
ListenEvent: TOnReceiveEvent; OnStopListening: TOnStopListenEvent;
OnError: TOnRequestError;
OnAuthRevoked: TOnAuthRevokedEvent = nil;
DoNotSynchronizeEvents: boolean = false): IFirebaseEvent;
The function returns an interface to IFirebaseEvent to stop the listener again.
You can also start multiple listeners, but each needs its own IFirebaseEvent variable. As soon as the IFirebaseEvent is freed, the listener thread is automatically terminated.
The callback function ListenEvent
will be called when there is a data change with the node addressed by the database path passed in ResourceParams
.
With the default value DoNotSynchronizeEvents=false
the functions ListenEvent
, OnError
, and OnAuthRevoked
are called in the main thread to ensure that the GUI can be accessed within these events. If there is no GUI access in the events and for possible database access, a separate database session is available, the necessary synchronization can be omitted with DoNotSynchronizeEvents=true
.
TOnReceiveEvent = procedure(const Event: string;
Params: TRequestResourceParam; JSONObj: TJSONObject) of object;
In the event parameter string, we expect either put
when the entire node should be replaced on the client-side. A patch
will be received if the data
in the resulting JSON is just a part of the monitored JSON object. The part concerns the relative database path. A cancel
will be received in case of unexpected errors. For more information about cancel
see also the Firebase Documentation.
The JSONObj
contains for put
and patch
the following data
JSON object:
data: {"path": <RelativeDBpath>, "data": {<JSONObjectofNodeData>}}
The following constants have been defined in FB4D.Interfaces to compare the event
and to read the JSONObj
:
const
cEventPut = 'put';
cEventPatch = 'patch';
cEventCancel = 'cancel';
cData = 'data';
cPath = 'path';
The callback function OnStopListening
will be called when the listener was stopped. This happens as a result if the listener was stopped by the application (via IFirebaseEvent.StopListening
) or because the internet connection was interrupted. In such a case, you should restart the listener when the internet connection becomes available again. Additional to the OnStopListening
you will get a callback at the function 'OnError' to be informed about the concrete error reason.
The optional callback function 'OnAuthRevoked' informs you when the authentication token was renewed automatically by the listener.
Hint: The former method function IRealTimeDB.GetLastKeepAliveTimeStamp: TDateTime
is replaced by the new method IFirebaseEvent.GetLastReceivedMsg
.
With this method, a server variable (the server timestamp which is number as Unix formatted timestamp) can be written into a node of the given database path. As result, the server time will be returned.
function GetServerVariablesSynchronous(const ServerVarName: string;
ResourceParams: TRequestResourceParam): TJSONValue;
Have you discovered an error? Or is something unclear? Please let us know in the discussion forum.
Schneider Infosystems Ltd. CH-6340 Baar, Switzerland, www.schneider-infosys.ch
Introduction into FB4D
Getting Started
Fundamental Principles
Project Settings
GUI Pattern Self-Registration
RT-DB Sample Applications
Firestore Chat Sample Applications
PhotoBox demonstrates Firestore, Storage, VisionML
Interface Reference
Configuration and Class Factory
Helper Classes
Authentication