Files
fps_project_1/addons/godot-firebase/database/once_reference.gd

125 lines
3.8 KiB
GDScript

class_name FirebaseOnceDatabaseReference
extends Node
## @meta-authors BackAt50Ft
## @meta-version 1.0
## A once off reference to a location in the Realtime Database.
## Documentation TODO.
signal once_successful(dataSnapshot)
signal once_failed()
signal push_successful()
signal push_failed()
const ORDER_BY : String = "orderBy"
const LIMIT_TO_FIRST : String = "limitToFirst"
const LIMIT_TO_LAST : String = "limitToLast"
const START_AT : String = "startAt"
const END_AT : String = "endAt"
const EQUAL_TO : String = "equalTo"
@onready var _oncer = $Oncer
@onready var _pusher = $Pusher
var _auth : Dictionary
var _config : Dictionary
var _filter_query : Dictionary
var _db_path : String
const _separator : String = "/"
const _json_list_tag : String = ".json"
const _query_tag : String = "?"
const _auth_tag : String = "auth="
const _auth_variable_begin : String = "["
const _auth_variable_end : String = "]"
const _filter_tag : String = "&"
const _escaped_quote : String = '"'
const _equal_tag : String = "="
const _key_filter_tag : String = "$key"
var _headers : PackedStringArray = []
func set_db_path(path : String, filter_query_dict : Dictionary) -> void:
_db_path = path
_filter_query = filter_query_dict
func set_auth_and_config(auth_ref : Dictionary, config_ref : Dictionary) -> void:
_auth = auth_ref
_config = config_ref
#
# Gets a data snapshot once at the position passed in
#
func once(reference : String) -> void:
var ref_pos = _get_list_url() + _db_path + _separator + reference + _get_remaining_path()
_oncer.request(ref_pos, _headers, HTTPClient.METHOD_GET, "")
func _get_remaining_path(is_push : bool = true) -> String:
var remaining_path = ""
if _filter_query_empty() or is_push:
remaining_path = _json_list_tag + _query_tag + _auth_tag + Firebase.Auth.auth.idtoken
else:
remaining_path = _json_list_tag + _query_tag + _get_filter() + _filter_tag + _auth_tag + Firebase.Auth.auth.idtoken
if Firebase.emulating:
remaining_path += "&ns="+_config.projectId+"-default-rtdb"
return remaining_path
func _get_list_url(with_port:bool = true) -> String:
var url = Firebase.Database._base_url.trim_suffix(_separator)
if with_port and Firebase.emulating:
url += ":" + _config.emulators.ports.realtimeDatabase
return url + _separator
func _get_filter():
if _filter_query_empty():
return ""
var filter = ""
if _filter_query.has(ORDER_BY):
filter += ORDER_BY + _equal_tag + _escaped_quote + _filter_query[ORDER_BY] + _escaped_quote
_filter_query.erase(ORDER_BY)
else:
filter += ORDER_BY + _equal_tag + _escaped_quote + _key_filter_tag + _escaped_quote # Presumptuous, but to get it to work at all...
for key in _filter_query.keys():
filter += _filter_tag + key + _equal_tag + _filter_query[key]
return filter
func _filter_query_empty() -> bool:
return _filter_query == null or _filter_query.is_empty()
func on_get_request_complete(result : int, response_code : int, headers : PackedStringArray, body : PackedByteArray) -> void:
if response_code == HTTPClient.RESPONSE_OK:
var bod = Utilities.get_json_data(body)
once_successful.emit(bod)
else:
once_failed.emit()
func on_push_request_complete(result : int, response_code : int, headers : PackedStringArray, body : PackedByteArray) -> void:
if response_code == HTTPClient.RESPONSE_OK:
push_successful.emit()
else:
push_failed.emit()
func push(data : Dictionary) -> void:
var to_push = JSON.stringify(data)
_pusher.request(_get_list_url() + _db_path + _get_remaining_path(true), _headers, HTTPClient.METHOD_POST, to_push)
func update(path : String, data : Dictionary) -> void:
path = path.strip_edges(true, true)
if path == _separator:
path = ""
var to_update = JSON.stringify(data)
var resolved_path = (_get_list_url() + _db_path + "/" + path + _get_remaining_path())
_pusher.request(resolved_path, _headers, HTTPClient.METHOD_PATCH, to_update)