@@ -40,39 +40,27 @@ const _MAX_POOLED_REQUEST_AGE = 30
4040## The code indicating the request Firestore is processing.
4141## See @[enum FirebaseFirestore.Requests] to get a full list of codes identifiers.
4242## @enum Requests
43- var request : int = - 1
44-
45- ## Whether cache files can be used and generated.
46- ## @default true
47- var persistence_enabled : bool = false
48-
49- ## Whether an internet connection can be used.
50- ## @default true
51- var networking : bool = true : set = set_networking
43+ var request : int = - 1
5244
5345## A Dictionary containing all authentication fields for the current logged user.
5446## @type Dictionary
55- var auth : Dictionary
47+ var auth : Dictionary
5648
57- var _config : Dictionary = {}
49+ var _config : Dictionary = {}
5850var _cache_loc : String
5951var _encrypt_key := "5vg76n90345f7w390346" if Utilities .is_web () else OS .get_unique_id ()
6052
6153
62- var _base_url : String = ""
63- var _extended_url : String = "projects/[PROJECT_ID]/databases/(default)/documents/"
64- var _query_suffix : String = ":runQuery"
54+ var _base_url : String = ""
55+ var _extended_url : String = "projects/[PROJECT_ID]/databases/(default)/documents/"
56+ var _query_suffix : String = ":runQuery"
57+ var _agg_query_suffix : String = ":runAggregationQuery"
6558
6659# var _connect_check_node : HTTPRequest
6760
68- var _request_list_node : HTTPRequest
69- var _requests_queue : Array = []
70- var _current_query : FirestoreQuery
71-
72- var _offline : bool = false : set = _set_offline
73-
74- func _ready () -> void :
75- pass
61+ var _request_list_node : HTTPRequest
62+ var _requests_queue : Array = []
63+ var _current_query : FirestoreQuery
7664
7765## Returns a reference collection by its [i]path[/i].
7866##
@@ -99,49 +87,69 @@ func collection(path : String) -> FirestoreCollection:
9987## Issue a query checked your Firestore database.
10088##
10189## [b]Note:[/b] a [code]FirestoreQuery[/code] object needs to be created to issue the query.
102- ## This method will return a [code]FirestoreTask[/code] object, representing a reference to the request issued.
103- ## If saved into a variable, the [code]FirestoreTask[/code] object can be used to yield checked the [code]result_query(result)[/code] signal, or the more generic [code]task_finished(result)[/code] signal.
104- ##
105- ## ex.
106- ## [code]var query_task : FirestoreTask = Firebase.Firestore.query(FirestoreQuery.new())[/code]
107- ## [code]await query_task.task_finished[/code]
108- ## Since the emitted signal is holding an argument, it can be directly retrieved as a return variable from the [code]yield()[/code] function.
90+ ## When awaited, this function returns the resulting array from the query.
10991##
11092## ex.
111- ## [code]var result : Array = await query_task.task_finished [/code]
93+ ## [code]var query_results = wait Firebase.Firestore.query(FirestoreQuery.new()) [/code]
11294##
11395## [b]Warning:[/b] It currently does not work offline!
11496##
11597## @args query
11698## @arg-types FirestoreQuery
117- ## @return FirestoreTask
99+ ## @return Array[FirestoreDocument]
118100func query (query : FirestoreQuery ) -> Array :
101+ if query .aggregations .size () > 0 :
102+ Firebase ._printerr ("Aggregation query sent with normal query call: " + str (query ))
103+ return []
104+
119105 var task : FirestoreTask = FirestoreTask .new ()
120106 task .action = FirestoreTask .Task .TASK_QUERY
121- var body : Dictionary = { structuredQuery = query .query }
122- var url : String = _base_url + _extended_url + _query_suffix
123-
107+ var body : Dictionary = { structuredQuery = query .query }
108+ var url : String = _base_url + _extended_url + _query_suffix
109+
124110 task .data = query
125111 task ._fields = JSON .stringify (body )
126112 task ._url = url
127113 _pooled_request (task )
128114 return await _handle_task_finished (task )
129-
130-
131- ## Request a list of contents (documents and/or collections) inside a collection, specified by its [i]id[/i]. This method will return a [code]FirestoreTask[/code] object, representing a reference to the request issued. If saved into a variable, the [code]FirestoreTask[/code] object can be used to yield checked the [code]result_query(result)[/code] signal, or the more generic [code]task_finished(result)[/code] signal.
132- ## [b]Note:[/b] [code]order_by[/code] does not work in offline mode.
133- ## ex.
134- ## [code]var query_task : FirestoreTask = Firebase.Firestore.query(FirestoreQuery.new())[/code]
135- ## [code]await query_task.task_finished[/code]
136- ## Since the emitted signal is holding an argument, it can be directly retrieved as a return variable from the [code]yield()[/code] function.
115+
116+ ## Issue an aggregation query (sum, average, count) against your Firestore database;
117+ ## cheaper than a normal query and counting (for instance) values directly.
118+ ##
119+ ## [b]Note:[/b] a [code]FirestoreQuery[/code] object needs to be created to issue the query.
120+ ## When awaited, this function returns the result from the aggregation query.
137121##
138122## ex.
139- ## [code]var result : Array = await query_task.task_finished[/code]
123+ ## [code]var query_results = await Firebase.Firestore.query(FirestoreQuery.new())[/code]
124+ ##
125+ ## [b]Warning:[/b] It currently does not work offline!
140126##
127+ ## @args query
128+ ## @arg-types FirestoreQuery
129+ ## @return Variant representing the array results of the aggregation query
130+ func aggregation_query (query : FirestoreQuery ) -> Variant :
131+ if query .aggregations .size () == 0 :
132+ Firebase ._printerr ("Aggregation query sent with no aggregation values: " + str (query ))
133+ return 0
134+
135+ var task : FirestoreTask = FirestoreTask .new ()
136+ task .action = FirestoreTask .Task .TASK_AGG_QUERY
137+
138+ var body : Dictionary = { structuredAggregationQuery = { structuredQuery = query .query , aggregations = query .aggregations } }
139+ var url : String = _base_url + _extended_url + _agg_query_suffix
140+
141+ task .data = query
142+ task ._fields = JSON .stringify (body )
143+ task ._url = url
144+ _pooled_request (task )
145+ var result = await _handle_task_finished (task )
146+ return result
147+
148+ ## Request a list of contents (documents and/or collections) inside a collection, specified by its [i]id[/i]. This method will return an Array[FirestoreDocument]
141149## @args collection_id, page_size, page_token, order_by
142150## @arg-types String, int, String, String
143151## @arg-defaults , 0, "", ""
144- ## @return FirestoreTask
152+ ## @return Array[FirestoreDocument]
145153func list (path : String = "" , page_size : int = 0 , page_token : String = "" , order_by : String = "" ) -> Array :
146154 var task : FirestoreTask = FirestoreTask .new ()
147155 task .action = FirestoreTask .Task .TASK_LIST
@@ -160,38 +168,6 @@ func list(path : String = "", page_size : int = 0, page_token : String = "", ord
160168 return await _handle_task_finished (task )
161169
162170
163- func set_networking (value : bool ) -> void :
164- if value :
165- enable_networking ()
166- else :
167- disable_networking ()
168-
169-
170- func enable_networking () -> void :
171- if networking :
172- return
173- networking = true
174- _base_url = _base_url .replace ("storeoffline" , "firestore" )
175- for coll in get_children ():
176- if coll is FirestoreCollection :
177- coll ._base_url = _base_url
178-
179-
180- func disable_networking () -> void :
181- if not networking :
182- return
183- networking = false
184- # Pointing to an invalid url should do the trick.
185- _base_url = _base_url .replace ("firestore" , "storeoffline" )
186- for coll in get_children ():
187- if coll is FirestoreCollection :
188- coll ._base_url = _base_url
189-
190-
191- func _set_offline (value : bool ) -> void :
192- return # Since caching is causing a lot of issues, I'm turning it off for now. We will revisit this in the future, once we have some time to investigate why the cache is being corrupted.
193-
194-
195171func _set_config (config_json : Dictionary ) -> void :
196172 _config = config_json
197173 _cache_loc = _config ["cacheLocation" ]
@@ -213,10 +189,6 @@ func _check_emulating() -> void :
213189 _base_url = "http://localhost:{port} /{version} /" .format ({ version = _API_VERSION , port = port })
214190
215191func _pooled_request (task : FirestoreTask ) -> void :
216- if _offline :
217- task ._on_request_completed (HTTPRequest .RESULT_CANT_CONNECT , 404 , PackedStringArray (), PackedByteArray ())
218- return
219-
220192 if (auth == null or auth .is_empty ()) and not Firebase .emulating :
221193 Firebase ._print ("Unauthenticated request issued..." )
222194 Firebase .Auth .login_anonymous ()
@@ -252,11 +224,6 @@ func _on_FirebaseAuth_token_refresh_succeeded(auth_result : Dictionary) -> void:
252224 if coll is FirestoreCollection :
253225 coll .auth = auth
254226
255- func _on_connect_check_request_completed (result : int , _response_code , _headers , _body ) -> void :
256- _set_offline (result != HTTPRequest .RESULT_SUCCESS )
257- # _connect_check_node.request(_base_url)
258-
259-
260227func _on_FirebaseAuth_logout () -> void :
261228 auth = {}
262229
0 commit comments