@@ -2,20 +2,27 @@ import 'dart:async';
22
33import 'package:flutter/foundation.dart' ;
44import 'package:flutter_news_app_mobile_client_full_source_code/ads/ad_provider.dart' ;
5- import 'package:google_mobile_ads/google_mobile_ads.dart' ;
5+ import 'package:flutter_news_app_mobile_client_full_source_code/ads/models/native_ad.dart'
6+ as app_native_ad;
7+ import 'package:google_mobile_ads/google_mobile_ads.dart' as admob;
68import 'package:logging/logging.dart' ;
9+ import 'package:uuid/uuid.dart' ;
710
811/// {@template admob_ad_provider}
912/// A concrete implementation of [AdProvider] for Google AdMob.
1013///
1114/// This class handles the initialization of the Google Mobile Ads SDK
12- /// and the loading of native ads specifically for AdMob.
15+ /// and the loading of native ads specifically for AdMob. It adapts the
16+ /// AdMob-specific [admob.NativeAd] object into our generic [app_native_ad.NativeAd]
17+ /// model.
1318/// {@endtemplate}
1419class AdMobAdProvider implements AdProvider {
1520 /// {@macro admob_ad_provider}
16- AdMobAdProvider ({Logger ? logger}) : _logger = logger ?? Logger ('AdMobAdProvider' );
21+ AdMobAdProvider ({Logger ? logger})
22+ : _logger = logger ?? Logger ('AdMobAdProvider' );
1723
1824 final Logger _logger;
25+ final Uuid _uuid = const Uuid ();
1926
2027 /// The AdMob Native Ad Unit ID for Android.
2128 ///
@@ -54,7 +61,7 @@ class AdMobAdProvider implements AdProvider {
5461 Future <void > initialize () async {
5562 _logger.info ('Initializing Google Mobile Ads SDK...' );
5663 try {
57- await MobileAds .instance.initialize ();
64+ await admob. MobileAds .instance.initialize ();
5865 _logger.info ('Google Mobile Ads SDK initialized successfully.' );
5966 } catch (e) {
6067 _logger.severe ('Failed to initialize Google Mobile Ads SDK: $e ' );
@@ -64,24 +71,24 @@ class AdMobAdProvider implements AdProvider {
6471 }
6572
6673 @override
67- Future <NativeAd ?> loadNativeAd () async {
74+ Future <app_native_ad. NativeAd ?> loadNativeAd () async {
6875 if (_nativeAdUnitId.isEmpty) {
6976 _logger.warning ('No native ad unit ID configured for this platform.' );
7077 return null ;
7178 }
7279
7380 _logger.info ('Attempting to load native ad from unit ID: $_nativeAdUnitId ' );
7481
75- final completer = Completer <NativeAd ?>();
82+ final completer = Completer <admob. NativeAd ?>();
7683
77- final ad = NativeAd (
84+ final ad = admob. NativeAd (
7885 adUnitId: _nativeAdUnitId,
7986 factoryId: 'listTile' , // This ID must match a factory in your native code
80- request: const AdRequest (),
81- listener: NativeAdListener (
87+ request: const admob. AdRequest (),
88+ listener: admob. NativeAdListener (
8289 onAdLoaded: (ad) {
8390 _logger.info ('Native Ad loaded successfully.' );
84- completer.complete (ad as NativeAd );
91+ completer.complete (ad as admob. NativeAd );
8592 },
8693 onAdFailedToLoad: (ad, error) {
8794 _logger.severe ('Native Ad failed to load: $error ' );
@@ -114,6 +121,25 @@ class AdMobAdProvider implements AdProvider {
114121 completer.complete (null );
115122 }
116123
117- return completer.future;
124+ // Add a timeout to the future to prevent hanging if callbacks are not called.
125+ final googleNativeAd = await completer.future.timeout (
126+ const Duration (seconds: 15 ),
127+ onTimeout: () {
128+ _logger.warning ('Native ad loading timed out.' );
129+ ad.dispose (); // Dispose the ad if it timed out
130+ return null ;
131+ },
132+ );
133+
134+ if (googleNativeAd == null ) {
135+ return null ;
136+ }
137+
138+ // Map the Google Mobile Ads NativeAd to our generic NativeAd model.
139+ // Only the ID and the raw adObject are stored, as per the simplified model.
140+ return app_native_ad.NativeAd (
141+ id: _uuid.v4 (), // Generate a unique ID for our internal model
142+ adObject: googleNativeAd, // Store the original AdMob object
143+ );
118144 }
119145}
0 commit comments