What i've noticed is, its very slow when you intialized the sdk and show a banner, it something takes between 5 to 7 seconds to complete the initialization and then show the banner. I do call the ads initialize function in the app.component so i get it to run quickly but like i said its slow.
Another thing on interstitials is also it something takes about 5 to 6 seconds to load it.
I'm reporting because as compared to the admob-plus plugin, it takes between 2 to 3 seconds to load a banner or an interstitial.
Its a great work you've done so far
import { Injectable, NgZone } from '@angular/core';
import { Platform } from '@ionic/angular';
import { Router } from '@angular/router';
import { Subject } from 'rxjs';
import { environment } from 'src/environments/environment';
declare var admobNextGen: any;
@Injectable({
providedIn: 'root',
})
export class AdmobServices {
private admob: any = null;
private isSdkInitialized = false;
private pendingLoadOnPause = false;
isShowingFullscreenAd = false;
isAdSuppressed = false;
private lastFullscreenDismissedTime = 0;
private readonly FULLSCREEN_RESUME_DELAY = 1500;
rewardedAd: any;
hasUserGotReward = false;
rewardEarned$ = new Subject<void>();
private rewardResolver: ((rewarded: boolean) => void) | null = null;
private rewardPendingShow = false;
bannerAd: any;
appOpenAd: any;
appOpenDismissed$ = new Subject<void>();
lastAppOpenShownTime = 0;
readonly APP_OPEN_COOLDOWN = 30000;
constructor(
private platform: Platform,
private zone: NgZone,
) {
this.setupAdEvents();
this.setupAppOpenLifecycle();
}
// Helper to dynamically resolve global plugin reference
private resolveAdMob(): any {
if (this.admob) return this.admob;
this.admob =
(window as any).admobNextGen ||
(typeof admobNextGen !== 'undefined' ? admobNextGen : null);
return this.admob;
}
// ==================================================
// INITIALIZATION
// ==================================================
async initializeAds(): Promise<void> {
await this.platform.ready();
const admob = this.resolveAdMob();
if (!admob) {
console.error('AdMob Next Gen not available.');
return;
}
admob.initialize(
{
maxAdContentRating: 'G',
tagForChildDirectedTreatment: false,
tagForUnderAgeOfConsent: false,
},
() => {
this.zone.run(() => {
this.isSdkInitialized = true;
this.showBannerAd();
// If the user backgrounded the app while SDK was initializing, trigger load now
if (this.pendingLoadOnPause) {
this.pendingLoadOnPause = false;
this.loadAppOpenAd();
}
});
},
(error: any) => console.error('AdMob initialization failed:', error),
);
}
// ==================================================
// BANNER
// ==================================================
async showBannerAd(): Promise<void> {
await this.platform.ready();
const admob = this.resolveAdMob();
if (!admob || this.bannerAd) {
return;
}
try {
admob.createBanner({
adUnitId: environment.androidBannerAdId,
position: 'bottom',
size: 'ADAPTIVE',
isOverlapping: false,
collapsible: true,
retryInterval: 5000,
});
this.bannerAd = true;
} catch (error) {
console.error('Error creating banner:', error);
}
}
async hideBanner(): Promise<void> {
await this.platform.ready();
const admob = this.resolveAdMob();
if (!admob || !this.bannerAd) {
return;
}
try {
admob.removeBanner();
this.bannerAd = false;
} catch (error) {
console.error('Error removing banner:', error);
}
}
// ==================================================
// INTERSTITIAL
// ==================================================
async loadInterstitialAd(): Promise<void> {
await this.platform.ready();
const admob = this.resolveAdMob();
if (!admob) {
return;
}
try {
admob.createInterstitial({
adUnitId: environment.androidInterstitialAdId,
isAutoShow: false,
retryInterval: 5000,
});
} catch (error) {
console.error('Error creating interstitial:', error);
}
}
async showInterstitialAd() {
await this.platform.ready();
const admob = this.resolveAdMob();
this.isShowingFullscreenAd = true;
try {
admob.showInterstitial();
} catch (error) {
console.error('Error showing interstitial:', error);
this.isShowingFullscreenAd = false;
this.lastFullscreenDismissedTime = Date.now();
}
}
// ==================================================
// REWARDED
// ==================================================
async loadAdReward(): Promise<boolean> {
await this.platform.ready();
const admob = this.resolveAdMob();
if (!admob || this.rewardResolver) {
return false;
}
this.hasUserGotReward = false;
const result = new Promise<boolean>((resolve) => {
this.rewardResolver = resolve;
});
if (this.rewardedAd === true) {
this.rewardedAd = false;
this.showRewardedNow();
return result;
}
if (this.rewardedAd === 'loading') {
this.rewardPendingShow = true;
return result;
}
this.rewardedAd = 'loading';
this.rewardPendingShow = true;
try {
admob.createRewarded({
adUnitId: environment.androidRewardAdId,
isAutoShow: false,
retryInterval: 5000,
});
} catch (error) {
console.error('Error creating rewarded ad:', error);
this.rewardedAd = false;
this.rewardPendingShow = false;
this.resolveReward(false);
}
return result;
}
private showRewardedNow(): void {
const admob = this.resolveAdMob();
try {
this.isShowingFullscreenAd = true;
admob.showRewarded();
} catch (error) {
console.error('Error showing rewarded ad:', error);
this.isShowingFullscreenAd = false;
this.lastFullscreenDismissedTime = Date.now();
this.resolveReward(false);
}
}
private resolveReward(value: boolean): void {
if (!this.rewardResolver) {
return;
}
const resolve = this.rewardResolver;
this.rewardResolver = null;
resolve(value);
}
// ==================================================
// APP OPEN
// ==================================================
private setupAppOpenLifecycle(): void {
document.addEventListener(
'pause',
() => {
this.zone.run(() => {
if (this.isAdSuppressed || this.isShowingFullscreenAd) {
return;
}
if (this.isSdkInitialized) {
this.loadAppOpenAd();
} else {
// Queue load if SDK is still initializing
this.pendingLoadOnPause = true;
}
});
},
false,
);
document.addEventListener(
'resume',
() => {
this.zone.run(() => {
const admob = this.resolveAdMob();
if (!admob || this.isAdSuppressed || this.isShowingFullscreenAd) {
return;
}
if (Date.now() - this.lastFullscreenDismissedTime < this.FULLSCREEN_RESUME_DELAY) {
return;
}
if (Date.now() - this.lastAppOpenShownTime < this.APP_OPEN_COOLDOWN) {
return;
}
if (this.appOpenAd !== true) {
return;
}
this.showAppOpen();
});
},
false,
);
}
private loadAppOpenAd(): void {
const admob = this.resolveAdMob();
if (!admob || !this.isSdkInitialized || this.appOpenAd) {
return;
}
this.appOpenAd = 'loading';
try {
admob.loadAppOpenAd({
adUnitId: environment.androidAppOpenId,
isAutoShow: false,
retryInterval: 5000,
});
} catch (error) {
this.appOpenAd = false;
console.error('Error loading App Open ad:', error);
}
}
private showAppOpen(): void {
const admob = this.resolveAdMob();
if (!admob) return;
this.appOpenAd = false;
this.isShowingFullscreenAd = true;
try {
admob.showAppOpenAd();
} catch (error) {
console.error('Error showing App Open ad:', error);
this.isShowingFullscreenAd = false;
this.lastFullscreenDismissedTime = Date.now();
}
}
// ==================================================
// AD EVENTS
// ==================================================
private setupAdEvents(): void {
// ---- rewarded ----
document.addEventListener('on.rewarded.loaded', () => {
this.zone.run(() => {
this.rewardedAd = true;
if (this.rewardPendingShow) {
this.rewardPendingShow = false;
this.rewardedAd = false;
this.showRewardedNow();
}
});
});
document.addEventListener('on.rewarded.earned', () => {
this.zone.run(() => {
this.hasUserGotReward = true;
this.rewardEarned$.next();
this.resolveReward(true);
});
});
document.addEventListener('on.rewarded.shown', () => {
this.zone.run(() => {
this.isShowingFullscreenAd = true;
});
});
const rewardedClosed = () => {
this.zone.run(() => {
this.rewardedAd = false;
this.rewardPendingShow = false;
this.isShowingFullscreenAd = false;
this.lastFullscreenDismissedTime = Date.now();
this.resolveReward(false);
});
};
document.addEventListener('on.rewarded.dismissed', rewardedClosed);
document.addEventListener('on.rewarded.canceled', rewardedClosed);
document.addEventListener('on.rewarded.failed.show', (event: any) => {
console.error('Rewarded failed to show:', event);
rewardedClosed();
});
document.addEventListener('on.rewarded.failed.load', (event: any) => {
console.error('Rewarded failed to load:', event);
this.zone.run(() => {
this.rewardedAd = false;
this.rewardPendingShow = false;
this.resolveReward(false);
});
});
// ---- interstitial ----
document.addEventListener('on.interstitial.loaded', () => {
this.zone.run(() => {
console.log('inter-ad-loaded')
});
});
document.addEventListener('on.interstitial.failed.load', (event: any) => {
console.error('Interstitial failed to load:', event);
this.zone.run(() => {
});
});
const interstitialClosed = () => {
this.zone.run(() => {
this.isShowingFullscreenAd = false;
this.lastFullscreenDismissedTime = Date.now();
});
};
document.addEventListener('on.interstitial.dismissed', interstitialClosed);
document.addEventListener('on.interstitial.failed.show', (event: any) => {
console.error('Interstitial failed to show:', event);
interstitialClosed();
});
// ---- app open ----
document.addEventListener('on.appopen.loaded', () => {
this.zone.run(() => {
this.appOpenAd = true;
});
});
document.addEventListener('on.appopen.failed.load', (event: any) => {
console.error('App Open failed to load:', event);
this.zone.run(() => {
this.appOpenAd = false;
});
});
document.addEventListener('on.appopen.shown', () => {
this.zone.run(() => {
this.appOpenAd = false;
this.isShowingFullscreenAd = true;
this.lastAppOpenShownTime = Date.now();
});
});
const appOpenClosed = () => {
this.zone.run(() => {
this.appOpenAd = false;
this.isShowingFullscreenAd = false;
this.lastFullscreenDismissedTime = Date.now();
this.appOpenDismissed$.next();
});
};
document.addEventListener('on.appopen.dismissed', appOpenClosed);
document.addEventListener('on.appopen.failed.show', (event: any) => {
console.error('App Open failed to show:', event);
appOpenClosed();
});
}
}
What i've noticed is, its very slow when you intialized the sdk and show a banner, it something takes between 5 to 7 seconds to complete the initialization and then show the banner. I do call the ads initialize function in the app.component so i get it to run quickly but like i said its slow.
Another thing on interstitials is also it something takes about 5 to 6 seconds to load it.
I'm reporting because as compared to the admob-plus plugin, it takes between 2 to 3 seconds to load a banner or an interstitial.
Its a great work you've done so far
I'm pasting my code below
Describe the solution you'd like
loading and showing an ad, should be fast
Describe alternatives you've considered
No response