vivominigame / issues

vivo小游戏问题反馈和统一回复入口
13 stars 9 forks source link

广告报:undefined创建次数或者创建频率过高 #197

Closed shuizhongyueming closed 4 years ago

shuizhongyueming commented 4 years ago

相关信息

引擎

平台版本号:1063 平台版本名称:1.6.3.303

问题描述

创建广告,bannerAd, interstitialAd或者rewardedVideoAd没问题,但是调用show,会catch到错误:

{"data":{"errCode":30009,"errMsg":"undefined创建次数或者创建频率过高"},"code":30009}

查看了官网的广告错误码信息

30009 | 10秒内调用广告次数超过1次 | 降低广告展示频率,建议最少间隔10s

但是我这边是游戏启动之后,第一次调用,也是会这样,所以跟我这边的调用频率应该没有关系

复现步骤

使用的官方DEMO

function initbannerAd(){
  const bannerAd = qg.createBannerAd({
    posId:'广告ID'
  });
  bannerAd.onError(err => {
    console.log("banner广告加载失败", err);
  });

  bannerAd.show().then(()=>{ 
    console.log('banner广告展示完成');
  }).catch((err)=>{
    console.log('banner广告展示失败', JSON.stringify(err));
  })
}

在游戏启动之后,等待十秒执行

jesseband commented 4 years ago

https://minigame.vivo.com.cn/documents/#/lesson/open-ability/ad?id=%e5%b9%bf%e5%91%8a%e9%97%ae%e9%a2%98%e6%8e%92%e6%9f%a5%e8%87%aa%e6%b5%8bdemo%e4%b8%8b%e8%bd%bd

这个测试下 如果能复现 把广告id和包名提供下

shuizhongyueming commented 4 years ago

找到问题了,我这边用的白鹭引擎,可能版本有点旧吧,里面有一个Box2dweb的库,里面针对Object.defineProperty有一个polyfill:

   if(!(Object.prototype.defineProperty instanceof Function)
      && Object.prototype.__defineGetter__ instanceof Function
      && Object.prototype.__defineSetter__ instanceof Function)
   {
      Object.defineProperty = function(obj, p, cfg) {
         if(cfg.get instanceof Function)
            obj.__defineGetter__(p, cfg.get);
         if(cfg.set instanceof Function)
            obj.__defineSetter__(p, cfg.set);
      }
   }

但是小游戏平台下Function被改写过,用instanceof Function来判断是否为函数肯定是会失败的,这就导致这个polyfill会让Object.defineProperty里面的getset失效。

然后我看了下广告在vivo里面的内部实现,在继承这块,是有用到Object.defineProperty

    function i(e, t) {
        for (const a of Reflect.ownKeys(t))
            if ("constructor" !== a && "prototype" !== a && "name" !== a) {
                const r = Object.getOwnPropertyDescriptor(t, a);
                Object.defineProperty(e, a, r)
            }
    }
    t.mix = function(...e) {
        class t {
            constructor(...t) {
                i(this, new e[0](...t))
            }
        }
        for (const a of e)
            i(t, a),
            i(t.prototype, a.prototype);
        return t
    }

因为Object.defineProperty的异变,使得最终创建的bannerAd里面会丢失moduleName等属性,在调用show方法的时候才会诡异的出现"undefined创建次数或者创建频率过高",正常情况下,如果是频率过高,是会提示具体哪个广告模块的。

我这边把对Object.defineProperty的polyfill注释之后,再运行游戏,广告就能正确展示了😃