GodotNuts / GodotFirebase

Implementations of Firebase for Godot using GDScript
MIT License
558 stars 79 forks source link

[BUG] POSSIBLE bug and fix. RTDB get_event_data parsing multiple "events" #443

Open TrevorBlythe opened 2 weeks ago

TrevorBlythe commented 2 weeks ago

Describe the bug get_event_data not parsing correctly. From what I see, it takes a string of format: " event: (put/delete/idk) data: (some rtdb data associated " BUT, sometimes when working with rtdb, and multiple events happen at similar times, the strings would come in like this: " event: (put/delete/idk) data: (some rtdb data associated

event: (put/delete/idk) data: (some rtdb data associated " with multiple events... which makes me think this function should be fixed to handle when there are multiple "events" in the string

To Reproduce Have a listener to the rtdb path, and spam a bunch of changes at once.

Expected behavior For every change in the rtdb to show up in the new_data_update and patch_data_update signals

code that fixes it Not doing a pull request because not sure if this is a true bug or what. BUT THIS CODE DID FIX ALL OF MY RTDB PROBLEMS..

in the HTTPSSEClient.gd:

#all the old code remains the same except the functions i put here

func _parse_response_body(headers):
    var body = response_body.get_string_from_utf8()
    if body:
        var event_datas = get_event_data(body)
        var resize_response_body_to_zero_after_for_loop_flag = false
        for event_data in event_datas:
            if event_data.event != "keep-alive" and event_data.event != continue_internal:

                var result = Utilities.get_json_data(event_data.data)
                if result != null:
                    var parsed_text = result
                    if response_body.size() > 0: # stop here if the value doesn't parse
                        #response_body.resize(0) old line of code
                        resize_response_body_to_zero_after_for_loop_flag = true #new line
                        new_sse_event.emit(headers, event_data.event, result)
            else:
                if event_data.event != continue_internal:
                    response_body.resize(0)
        if resize_response_body_to_zero_after_for_loop_flag:
            response_body.resize(0)

func get_event_data(body : String) -> Array:
    var results = []
    var start_idx = 0

    if body.find(event_tag, start_idx) == -1:
        return [{"event":continue_internal}]

    while true:
        # Find the index of the next event tag
        var event_idx = body.find(event_tag, start_idx)
        if event_idx == -1:
            break  # No more events found

        # Find the index of the corresponding data tag
        var data_idx = body.find(data_tag, event_idx + event_tag.length())
        if data_idx == -1:
            break  # No corresponding data found

        # Extract the event
        var event_value = body.substr(event_idx + event_tag.length(), data_idx - (event_idx + event_tag.length())).strip_edges()
        if event_value == "":
            break  # No valid event value found

        # Extract the data
        var data_end = body.find(event_tag, data_idx)  # Assume data ends at the next event tag
        if data_end == -1:
            data_end = body.length()  # If no new event tag, read till the end of the body

        var data_value = body.substr(data_idx + data_tag.length(), data_end - (data_idx + data_tag.length())).strip_edges()
        if data_value == "":
            break  # No valid data found

        # Append the event and data to results
        results.append({"event": event_value, "data": data_value})
        # Update the start index for the next iteration
        start_idx = data_end  # Move past the current data section

    return results

THIS IS UNTESTED ONLY TESTED WITH MY PROJECT THAT ONLY USES RTDB, it should work the same with other firebase things that use the HTTPSSEClient.gd file.

TrevorBlythe commented 2 weeks ago

Im adding the realtime database in the title so if anyone else experiences the issue just copy paste my code and it should fix