Flutter мобильные объявления google показывают только тестовые объявления на IOS

#ios #flutter #dart #admob #googlemobileads

#iOS #трепетать #дротик #admob #googlemobileads

Вопрос:

У меня есть следующее хранилище объявлений

 import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'dart:io';  import 'package:flutter/foundation.dart'; import 'package:my_app/data/api/constants.dart';  class AdMobRepository {  late String liveBannerAdId;  late String liveInterstitualAdId;  late String liveRewardedAdId;   AdMobRepository() {  if (Platform.isAndroid) {  liveBannerAdId = Constants.androidBannedAdId;  liveInterstitualAdId = Constants.androidInterstitualAdId;  liveRewardedAdId = Constants.androidRewardedAdId;  } else if (Platform.isIOS) {  liveBannerAdId = Constants.iosBannerAdId;  liveInterstitualAdId = Constants.iosInterstitualAdId;  liveRewardedAdId = Constants.iosRewardedAdId;  } else {  liveBannerAdId = "";  liveInterstitualAdId = "";  liveRewardedAdId = "";  }  }   BannerAd getBannerAd({  required AdSize size,  void Function(Ad, LoadAdError)? onFailedLoad,  void Function(Ad)? onLoad,  void Function(Ad)? onAdOpened,  void Function(Ad)? onAdImpression,  }) {  return BannerAd(  adUnitId: kReleaseMode ? liveBannerAdId : BannerAd.testAdUnitId,  request: AdRequest(),  size: size,  listener: BannerAdListener(  onAdFailedToLoad: onFailedLoad ?? onFailedLoadFallback,  onAdLoaded: onLoad,  onAdImpression: onAdImpression,  onAdOpened: onAdOpened,  ),  );  }   void onFailedLoadFallback(Ad ad, LoadAdError error) {  ad.dispose();  }   void getInterstitualAd({required void Function(LoadAdError) onFailedLoad, void Function(InterstitialAd)? onLoad}) {  InterstitialAd.load(  adUnitId: kReleaseMode ? liveInterstitualAdId : InterstitialAd.testAdUnitId,  request: AdRequest(),  adLoadCallback: InterstitialAdLoadCallback(  onAdLoaded: onLoad ?? onInterstitialAdLoadedFallback,  onAdFailedToLoad: onFailedLoad,  ),  );  }   void onInterstitialAdLoadedFallback(InterstitialAd ad) {  ad.fullScreenContentCallback = FullScreenContentCallback(  onAdDismissedFullScreenContent: (ad) =gt; ad.dispose(), onAdFailedToShowFullScreenContent: (ad, error) =gt; ad.dispose());  }   void getRewardAd({required String userId, required void Function(LoadAdError) onFailedLoad, void Function(RewardedAd)? onLoad}) {  RewardedAd.load(  adUnitId: kReleaseMode ? liveRewardedAdId : RewardedAd.testAdUnitId,  request: AdRequest(),  rewardedAdLoadCallback: RewardedAdLoadCallback(  onAdLoaded: onLoad ?? onRewardedAdLoadedFallback,  onAdFailedToLoad: onFailedLoad,  ),  serverSideVerificationOptions: ServerSideVerificationOptions(userId: userId),  );  }   void onRewardedAdLoadedFallback(RewardedAd ad) {  ad.fullScreenContentCallback = FullScreenContentCallback(  onAdDismissedFullScreenContent: (ad) =gt; ad.dispose(), onAdFailedToShowFullScreenContent: (ad, error) =gt; ad.dispose());  } }  

И у меня есть следующий виджет для баннерной рекламы

 class MyBannerAd extends StatefulWidget {   const MyBannerAd();   @override  _MyBannerAdState createState() =gt; _MyBannerAdState(); }  class _MyBannerAdState extends Statelt;MyBannerAdgt; {  late AdSize adSize;  late AdMobRepository adRepository;  late AnalyticsRepository analyticsRepository;  bool adLoaded = false;  BannerAd? anchoredBanner;   @override  void initState() {  super.initState();  adRepository = context.readlt;AdMobRepositorygt;();  analyticsRepository = context.readlt;AnalyticsRepositorygt;();   if (SizerUtil.deviceType != DeviceType.mobile amp;amp; SizerUtil.orientation == Orientation.portrait) {  adSize = AdSize.leaderboard;  } else {  adSize = AdSize.largeBanner;  }   final bannerAd = adRepository.getBannerAd(  size: adSize,  onFailedLoad: (ad, error) {  print('banner ad failed to load: $error');  ad.dispose();  },  onLoad: (ad) {  setState(() {  adLoaded = true;  anchoredBanner = ad as BannerAd?;  });  },  onAdImpression: (_) {  analyticsRepository.sendBannerAdShownEvent();  },  onAdOpened: (_) {  analyticsRepository.sendBannerAdClickEvent();  },  );   bannerAd.load();  }   @override  void dispose() {  super.dispose();  anchoredBanner?.dispose();  }   @override  Widget build(BuildContext context) {  return BlocBuilderlt;SubscriptionBloc, SubscriptionStategt;(  builder: (context, state) {  final isLoaded = !adLoaded;   if (isLoaded || state.hasSubscribed || anchoredBanner == null) return SizedBox.shrink();   return Container(  color: Colors.transparent,  width: anchoredBanner!.size.width.toDouble(),  height: anchoredBanner!.size.height.toDouble(),  child: Center(  child: Container(  color: Colors.white,  child: AdWidget(  ad: anchoredBanner!,  ),  ),  ),  );  },  );  } }  

Но на IOS он всегда показывает тестовую рекламу. Как это может быть, если приложение построено в режиме выпуска flutter с flutter build ios --release помощью ? Приложение в настоящее время находится на рассмотрении, и я подумал, что эти объявления перестанут быть тестовыми, когда они будут в прямом эфире в app Store.

Но Apple прислала нам следующее сообщение

Мы заметили, что ваше приложение или его скриншоты содержат тестовую рекламу. Приложения или элементы метаданных, включающие функции, предназначенные для тестирования или демонстрации, не подходят для магазина приложений.

следующие шаги

Чтобы устранить эту проблему, пожалуйста, измените свое приложение, чтобы завершить, удалить или полностью настроить все частично реализованные функции. Пожалуйста, убедитесь, что ваши скриншоты не содержат изображений демонстрационного, тестового или другого неполного контента

Итак, как мне избавиться от тестовой рекламы? Я пропустил какую-то настройку XCode или?

Я использую

 flutter: 2.5.3 google_mobile_ads: ^0.13.4  

И я также добавил идентификатор GADApplicationIdentifier в свой список info.plist

 lt;keygt;GADApplicationIdentifierlt;/keygt; lt;stringgt;{here I have the app Id}lt;/stringgt;  

И я тестирую на реальном устройстве с помощью сборки testflight

Примечание сбоку:

В настройках admob я добавил следующий тестовый IDFA

00000000-0000-0000-0000-000000000000

что, похоже, работает для тестовой рекламы на всех устройствах IOS.

Комментарии:

1. Вы установили значение 00000000-0000-0000-0000-000000000000 в настройках тестовых устройств консоли AdMob?

2. Да, я добавил его в разделе AdMob gt; Настройки gt;gt; Тестовые устройства

Ответ №1:

Оказывается, мне нужно было удалить 00000000-0000-0000-0000-000000000000 из настроек теста на admob. После этого я больше не получаю тестовые объявления, но теперь я получаю объявления в сборке релиза.

Ответ №2:

Вам не нужно вносить какие-либо изменения в код.

следующие шаги

Чтобы устранить эту проблему, пожалуйста, измените свое приложение, чтобы завершить, удалить или полностью настроить все частично реализованные функции. Пожалуйста, убедитесь, что ваши скриншоты не содержат изображений демонстрационного, тестового или другого неполного контента

Чтобы устранить вышеуказанный отказ, все, что вам нужно сделать, это удалить баннерную рекламу со своих скриншотов и снова отправить на утверждение.