poingstudios / godot-admob-plugin

This repository is for Godot's Addons to integrate natively AdMob to your Game Project without much configurations and directly inside Godot Editor!
https://poingstudios.github.io/godot-admob-plugin/
MIT License
312 stars 22 forks source link

App crash on remove node from tree after loading ad #122

Closed bayu-sw closed 9 months ago

bayu-sw commented 11 months ago

Godot version

4.1.2

Plugin version

v3.0.0

Phone information

OPPO A78 with Android 13

Issue description

App crash

Steps to reproduce

  1. ... do like the doc and try add ad format Rewarded
  2. in runtime after the app call this RewardedAdLoader.new().load(unit_id, AdRequest.new(), rewarded_ad_load_callback)
  3. immediately remove the node from tree before any of rewarded_ad_load_callback callback was called
  4. app crash

Additional context

note: i did use this on the node

func _exit_tree():
    if _rewarded_ad:
        _rewarded_ad.destroy()
        _rewarded_ad = null

but app still crash

I thing it happen because the plugin was trying to call the callback after finishing loading ads but the callback was not there because the node already removed from tree.

My workaround was like this

class_name RewardedAdLoader
#...
func load(
    owner_node : Node, # add this
    ad_unit_id : String, 
    ad_request : AdRequest, 
    rewarded_ad_load_callback := RewardedAdLoadCallback.new()) -> void:

    if _plugin:
        _plugin.load(ad_unit_id, ad_request.convert_to_dictionary(), ad_request.keywords, _uid)
        _plugin.connect("on_rewarded_ad_loaded", func(uid : int):
            #if uid == _uid:
            if uid == _uid and owner_node: # check if owner_node still exist
                rewarded_ad_load_callback.on_ad_loaded.call(RewardedAd.new(uid))
        )
        _plugin.connect("on_rewarded_ad_failed_to_load", func(uid : int, load_ad_error_dictionary : Dictionary): 
            #if uid == _uid:
            if uid == _uid and owner_node:
                rewarded_ad_load_callback.on_ad_failed_to_load.call(LoadAdError.create(load_ad_error_dictionary))
        )

then in the node call this

func _on_load_pressed():
    #...
    #RewardedAdLoader.new().load(unit_id, AdRequest.new(), rewarded_ad_load_callback)
    RewardedAdLoader.new().load(self, unit_id, AdRequest.new(), rewarded_ad_load_callback)

The the issue was resolved.

I did not test this on ios or other ad format but i think the issue was there too

gumaciel commented 11 months ago

Hi, thank you very much for reporting this bug, it seems like a critical bug and I'm looking for it!

bayu-sw commented 11 months ago

without breaking compatibility 🤔


class_name RewardedAdLoader
#...
func load(
#...
    _plugin.connect("on_rewarded_ad_loaded", func(uid : int):
        #if uid == _uid:
        if uid == _uid and rewarded_ad_load_callback.on_ad_loaded.is_valid():
            rewarded_ad_load_callback.on_ad_loaded.call(RewardedAd.new(uid))
        )
gumaciel commented 9 months ago

@bayu-sw should be fixed at https://github.com/Poing-Studios/godot-admob-plugin/releases/tag/v3.1.0 please test it