我正在使用 React Native expo 构建一个应用程序。我正在尝试实施激励广告。我从文档中复制了代码并且它有效。在我的应用程序中,用户可以观看任意数量的广告来赚取游戏币。问题在于我的实现中,激励广告只能看到一次,如果用户尝试再观看一个广告,用户会看到错误:
错误:RewardedAd.show() 请求的 RewardedAd 尚未加载并且 无法显示。
这个实现是模态的。因此,如果我关闭模式,打开它并按下按钮以再次观看激励广告,它就会起作用。由于这对用户来说不是一个好的体验,因此即使不关闭模式也应该看到广告。如果有什么办法可以解决这个问题,我将非常高兴。
这是我的实现:
import { useEffect, useState } from "react";
import {
RewardedAd,
RewardedAdEventType,
TestIds,
} from "react-native-google-mobile-ads";
const adUnitId = __DEV__
? TestIds.REWARDED
: "ca-app-pub-xxxxxxxxxxxxx/yyyyyyyyyyyyyy";
const rewarded = RewardedAd.createForAdRequest(adUnitId);
export const useRewardedAd = () => {
const [loaded, setLoaded] = useState(false);
const watchAd = () => {
if (loaded) {
rewarded.show();
}
};
useEffect(() => {
const unsubscribeLoaded = rewarded.addAdEventListener(
RewardedAdEventType.LOADED,
() => {
setLoaded(true);
}
);
const unsubscribeEarned = rewarded.addAdEventListener(
RewardedAdEventType.EARNED_REWARD,
(reward) => {
console.log("User earned reward of ", reward);
}
);
// Start loading the rewarded ad straight away
rewarded.load();
// Unsubscribe from events on unmount
return () => {
unsubscribeLoaded();
unsubscribeEarned();
};
}, []);
// No advert ready to show yet
if (!loaded) {
return null;
}
return watchAd;
};
我在这个组件中使用了watchAd:
import { View, Text, Alert } from "react-native";
import React, { useContext } from "react";
import { Entypo, FontAwesome, FontAwesome5 } from "@expo/vector-icons";
import EarnRow from "./EarnRow/EarnRow";
import { PlayerInformationContext } from "@/context/PlayerInformation";
import { useRewardedAd } from "@/hooks/useRewardedAd/useRewardedAd";
const Earn = () => {
const watchAd = useRewardedAd();
const {
money,
seenAdsCount,
health,
setHealth,
setMoney,
handleSeenAdsCount,
} = useContext(PlayerInformationContext);
const handleEarn = async (type: string) => {
switch (type) {
case "getMoney":
if (seenAdsCount < 10) {
handleSeenAdsCount(seenAdsCount + 1);
}
if (watchAd) {
watchAd();
}
break;
case "getHealth":
if (money >= 100) {
setHealth(health + 12);
setMoney(money - 100);
Alert.alert("Enerji Topladın!", "12 enerji puanı kazandın!");
} else {
Alert.alert("Yetersiz Altın!", "Bu işlem için yeterli altının yok.");
}
break;
default:
break;
}
};
return (
<View className="w-full h-full items-start justify-start">
<Text className="w-full mt-10 text-center text-white font-bold text-4xl">
Kazan
</Text>
<EarnRow
icon={
<FontAwesome5
name="bitcoin"
size={40}
className="-rotate-12 bg-white rounded-full"
color="orange"
/>
}
coinAmount="+30"
rewardText="Ücretsiz"
rewardAction={() => handleEarn("getMoney")}
buttonIcon={<Entypo name="video" size={24} color="white" />}
/>
<EarnRow
icon={<FontAwesome name="heart" size={40} color="red" />}
coinAmount="+12"
rewardText="100"
rewardAction={() => handleEarn("getHealth")}
buttonIcon={
<FontAwesome5
name="bitcoin"
size={24}
className="-rotate-12 bg-white rounded-full"
color="orange"
/>
}
/>
</View>
);
};
export default Earn;
对于那些也有同样问题的人,我找到了解决方法:
const unsubscribeClosed = rewarded.addAdEventListener(
AdEventType.CLOSED,
() => {
rewarded.load();
Alert.alert("Tebrikler!", "Reklamı izleyerek ödül kazandın.");
}
);
这将在用户关闭广告时触发。它将加载新广告,当您按下按钮观看新广告时,它将毫无问题地打开。我在“react-native-google-mobile-ads”的 github 帐户上找到了它。 AdEventType 和其他方面还有更多事件。在这里你可以找到所有:
https://github.com/invertase/react-native-google-mobile-ads/blob/main/src/ads/RewardedAd.ts
以及“React Native Google Mobile Ads”的文档
https://docs.page/invertase/react-native-google-mobile-ads/displaying-ads