Ionic - Problems displaying AdMob banner/interstitial (iOS) - ios

There are no issues what so ever showing both banner and interstitial ads on Android devices but on iOS devices they somehow don't show, only blank box in footer area and no popup appears - however works perfectly fine on the emulator, displaying test ads.
In AdMob - I have created only one app (iOS) and therefor only have two Ad Unit IDs(Banner and Interstitial) which I use, can that be the issue or ?
You can see my code below:
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { AdMobFree, AdMobFreeBannerConfig, AdMobFreeInterstitialConfig } from '#ionic-native/admob-free';
import { ProjectlistPage } from '../pages/projectlist/projectlist';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = ProjectlistPage;
constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, private admobFree : AdMobFree) {
platform.ready().then(() => {
statusBar.styleDefault();
splashScreen.hide();
this.showAdmobBannerAds();
this.showAdmobInterstitialAds();
});
}
showAdmobBannerAds(){
const bannerConfig: AdMobFreeBannerConfig = {
id: 'ca-app-pub-xxxxxx',
isTesting: false,
autoShow: true,
};
this.admobFree.banner.config(bannerConfig);
this.admobFree.banner.prepare()
.then(() => {
this.admobFree.banner.show();
})
.catch(e => console.log(e));
}
showAdmobInterstitialAds(){
const interstitialConfig: AdMobFreeInterstitialConfig = {
id: 'ca-app-pub-xxxxxx',
isTesting: false,
autoShow: true,
};
this.admobFree.interstitial.config(interstitialConfig);
this.admobFree.interstitial.prepare()
.then(() => {
this.admobFree.interstitial.show();
})
.catch(e => console.log(e));
}
}
Anyone have any suggestions ?
Thanks.

This issue got resolved by adjusting payment details within AdMob to reflect 100% my companies DUNS info.
https://github.com/ratson/cordova-plugin-admob-free/issues/157#issuecomment-374006844

Related

Firebase Auth & AngularFire Not Working on IOS Device

I created an Ionic 5 + Capacitor + Firebase project and added the latest version of AngularFire to it.
Everything works perfectly on Desktop but when I launch on my iPhone, there is an error (Well, there is no error but the redirection of my first page does not work).
So, no error in the logs but a white screen.
After much research, I came to the following conclusion.
I use AngularFireAuthGuard as follows :
{
path: '',
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule),
...canActivate(() => redirectUnauthorizedTo(['landing']))
}
And my research made me realize that with latest version of AngularFire firebase Auth is not detected properly.
So I found a piece of code that solved the problem for me for a while :
import { Component } from '#angular/core';
import { Capacitor } from '#capacitor/core';
import { initializeApp } from 'firebase/app';
import { indexedDBLocalPersistence, initializeAuth } from 'firebase/auth';
import { environment } from 'src/environments/environment';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
})
export class AppComponent {
constructor() {
const app = initializeApp(environment.firebase);
if (Capacitor.isNativePlatform) {
initializeAuth(app, {
persistence: indexedDBLocalPersistence
});
}
}
}
As soon as I wanted to add the onAuthStateChanged in my app.component I got the following error :
auth/already-initialized
In my opinion, it might be because my app.module.ts looks like this :
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
IonicStorageModule.forRoot(),
AppRoutingModule,
AngularFireAuthModule,
AngularFireModule.initializeApp(environment.firebase)
],
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
bootstrap: [AppComponent],
})
My application is initialized here but if I delete it I get another injection error...
Do you have any ideas how I can fix the problem ?
Wondering if my problem is similarly related: signin link works on web and android, but in iOS the app opens, I see the link is received but then the signInWithEmailLink() promise neither resolves nor catches.
This is the code; I see the console.log and thereafter there's silence:
console.log(`incoming Passwordless Login Link for mail ${email}: ${uri}, ${originalLink}`);
signInWithEmailLink(this.auth, email, originalLink)
.then(cred => {
console.log("successfully logged in", email, cred);
window.localStorage.removeItem("emailForSignIn");
this.router.navigateByUrl("/home");
})
.catch((err) => {
console.error("signInLink err", JSON.stringify(err));
this.ngZone.run(() => this.router.navigateByUrl("/pwlsignup"));
});
After the call I do see a few lines of these though, looking into if it is related:
nw_protocol_boringssl_get_output_frames(1301) [C4.1:2][0x7fee0fe19300] get output frames failed, state 8196
2018-11-12 22:12:05.398615-0800 QQBCHAT[37807:7011607] TIC Read Status [4:0x0]: 1:57
EDIT: Yes, mine must be a different issue - and I found the solution too, just if anyone hits this with google search
https://github.com/angular/angularfire/issues/2979#issuecomment-940910213
import {
getAuth,
indexedDBLocalPersistence,
initializeAuth,
provideAuth,
} from '#angular/fire/auth';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
...
provideAuth(() => {
if (Capacitor.isNativePlatform()) {
return initializeAuth(getApp(), {
persistence: indexedDBLocalPersistence,
});
} else {
return getAuth();
}
}),
]
})

Can't open a deeplink in foreground with React Native for iOS

We are using firebase deeplinks in a react native application built for both iOS and Android.
Example deeplink: https://monedacacao.page.link/RifKomEk3bhNM9CW9?d=1
Expected behavior:
User scans a QR Code that contains a deeplink in QRScannerScreen
onSuccess (e) is triggered and the link is opened using Linking.openUr()
In ReduxNavigation Firebase.links().onLink() is triggered and redirects the user to SendDestinataryScreen
Actual behavior
In Android this works as intended, but on iOS Linking.openURL(e.data) opens a browser with the Firebase fallback link instead of triggering the Firebase.links.onLin() action.
If the link is clicked from outside the application it behaves as intended. So this problem only occurs when opening the link from inside the application.
QRScannerScreen.js
...
onSuccess (e) {
Linking
.openURL(e.data)
.catch(err => console.error('An error occured', err))
}
...
ReduxNavigation.js
import React from 'react'
import { BackHandler, Platform } from 'react-native'
import { addNavigationHelpers, NavigationActions } from 'react-navigation'
import { createReduxBoundAddListener } from 'react-navigation-redux-helpers'
import { connect } from 'react-redux'
import firebase from 'react-native-firebase'
import AppNavigation from './AppNavigation'
class ReduxNavigation extends React.Component {
constructor (props) {
super(props)
// handle deeplinking
firebase.links().onLink((url) => {
console.log('URL', url)
if (this.props.token) {
this.props.dispatch(NavigationActions.push({
routeName: 'SendDestinataryScreen',
params: { link: url }
}))
} else {
this.props.dispatch(NavigationActions.push({
routeName: 'LoginScreen'
}))
}
})
}
componentDidMount () {
if (Platform.OS === 'ios') return
BackHandler.addEventListener('hardwareBackPress', () => {
const { dispatch, nav } = this.props
// change to whatever is your first screen, otherwise unpredictable results may occur
if (nav.routes.length === 1 && (nav.routes[0].routeName === 'LaunchScreen')) {
return false
}
// if (shouldCloseApp(nav)) return false
dispatch({ type: 'Navigation/BACK' })
return true
})
}
componentWillUnmount () {
if (Platform.OS === 'ios') return
BackHandler.removeEventListener('hardwareBackPress')
}
render () {
return <AppNavigation navigation={addNavigationHelpers({ dispatch: this.props.dispatch, state: this.props.nav, addListener: createReduxBoundAddListener('root') })} />
}
}
const mapStateToProps = state => ({ nav: state.nav, token: state.authentication.token })
export default connect(mapStateToProps)(ReduxNavigation)

Why does the QR Scanner Ionic plugin generate an error?

EDIT: I managed to make the plugin work, but when I test the app on my iPhone and click the button, Xcode sends me a warning: THREAD WARNING: ['QRScanner'] took '468.501953' ms. Plugin should use a background thread.
I tried so many things and follow so many articles and tutorials (also here, on SO) to get rid of this. I'm building an Ionic app, using the QR Scanner plugin that this framework provides. My app.module.ts is:
// Here are the basic Ionic import statements.
// Eventually, I import the plugin to scan QR codes.
import { QRScanner, QRScannerStatus } from '#ionic-native/qr-scanner';
#NgModule({
declarations: [ MyApp, HomePage ],
imports: [ BrowserModule, IonicModule.forRoot(MyApp) ],
bootstrap: [IonicApp],
entryComponents: [ MyApp, HomePage ],
providers: [ StatusBar, SplashScreen, QRScanner,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
})
export class AppModule { }
The folder structure is:
My app has only one page, HomePage, and the content of the src/pages/home/home.ts file is:
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { QRScanner, QRScannerStatus } from '#ionic-native/qr-scanner';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController, private qrScanner: QRScanner) { }
scanQrCode() {
this.qrScanner.prepare().then((status: QRScannerStatus) => {
if (status.authorized) {
let scanSub = this.qrScanner.scan().subscribe((text: string) => { console.log('Scanned something', text);
this.qrScanner.hide();
scanSub.unsubscribe();
});
} else if (status.denied) {
// ...
} else {
// ...
}
}).catch((e: any) => console.log('Error is', e));
}
}
Inside the src/pages/home/home.html file, I have:
<ion-header>
<ion-navbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<button ion-button (click)="scanQrCode()"></button>
</ion-content>
I build the app and run it on my iPhone 5, but when I click the button to scan a code, Xcode sends this: Error is [Object object]. Do you know why?

AsyncStorage.setItem crashes iOS every time, works perfectly on Android, Expo

Here's what I'm importing:
import React, { Component } from 'react'
import {
Image,
Text,
TextInput,
Keyboard,
KeyboardAvoidingView,
TouchableOpacity,
View,
Linking,
AsyncStorage,
Alert
} from 'react-native'
here is the function that sets the state (called from TextInput below)
setName = (name, value) => {
AsyncStorage.setItem(name, value);
}
and here is how it is being called
<TextInput
keyboardType='default'
autoCapitalize='words'
returnKeyType='next'
onSubmitEditing={() => this.lastNamedRef.focus()}
underlineColorAndroid='transparent'
style={{flex:1}}
placeholder='Your first name'
value={this.state.firstName}
onChangeText={(text) => [this.validateInputLength(text, 2, 50, 'firstName'), this.setName('firstName', this.state.firstName)]}
/>
<TextInput
keyboardType='default'
autoCapitalize='words'
returnKeyType='done'
ref={lastNameRef => this.lastNamedRef = lastNameRef}
underlineColorAndroid='transparent'
style={{flex:1}}
placeholder='Your last name'
value={this.state.lastName}
onChangeText={(text) => [this.validateInputLength(text, 2, 50, 'lastName'), this.setName('lastName', this.state.lastName)]}
/>
If I remove the this.setName() function from the onChangeText in the TextInput the app does not crash, but when it is there it crashes on iOS, but not on Android. this.state.firstName and this.state.lastName is coming from AsyncStorage when componentWillMount() (below) being updated with the setName function (above)
componentWillMount() {
AsyncStorage.getItem('firstName').then((value) => this.setState({firstName:value}))
AsyncStorage.getItem('lastName').then((value) => this.setState({lastName:value}))
}
the AsyncStorage.getItem within componentWillMount() does not crash the app, but does not seem to load the data into the field inconsistently. Most times it loads, but not every time. AsyncStorage in general seems super buggy.
Here's the validateInputLength function
validateInputLength = (text, min=10, max=25, type) => {
if(text.length < min || text.length > max) {
if(type=='firstName') {
this.setState({firstName:text})
this.setState({firstNameValidated:false})
return false;
} else if (type=='lastName') {
this.setState({lastName:text})
this.setState({lastNameValidated:false})
return false;
}
} else {
if(type=='firstName') {
this.setState({firstName:text})
this.setState({firstNameValidated:true})
} else if (type=='lastName') {
this.setState({lastName:text})
this.setState({lastNameValidated:true})
}
}
}
... and here's the constructor
constructor(props) {
super(props)
this.state = {
firstName: '',
lastName: '',
firstNameValidated: false,
lastNameValidated: false,
};
}
This crashes expo on iOS whether it is on my iPhone or running in the simulator, without showing any errors. Any ideas?
You can only store strings in AsyncStorage if you attempt to store a JSON object for example expo crashes, this may be whats happening, try using JSON.stringify before storing objects

Ionic 2 cordova-plugin-mauron85-background-geolocation Not Updating UI

I'm new to Ionic and Typescript so apologies if I have this arse about face !
Im trying to build a simple iOS and Android app with Ionic 2 that simply displays the users current location, updating as they move.
The issue I am facing is that whilst I appear to be getting the co-ordinate locations come through the UI never updates to display the updated location.
I have created a provider using the cordova-plugin-mauron85-background-geolocation plugin as location.ts:
import { Injectable, NgZone} from '#angular/core';
import { BackgroundGeolocation } from 'ionic-native';
#Injectable()
export class LocationProvider {
public message: any = "I'm new here";
public latitude:number = 0.0;
public longitude:number = 0.0;
private zone: NgZone;
constructor() {
this.initialiseLocationManager();
}
initialiseLocationManager() {
let config = {
desiredAccuracy: 1,
stationaryRadius: 1,
distanceFilter: 1,
interval:1000,
activityType:'AutomotiveNavigation',
debug: true,
stopOnTerminate: true,
};
BackgroundGeolocation.configure(config)
.then(this.locationUpdated)
.catch((error) => {
console.log('BackgroundGeolocation error');
});
}
private locationUpdated(location) {
console.log('******* NEW LOCATION ********');
this.zone.run(() => {
this.latitude = location.latitude;
this.longitude = location.longitude;
});
BackgroundGeolocation.finish(); // FOR IOS ONLY
}
private error(error) {
console.log('ERROR');
}
public startTracking() {
BackgroundGeolocation.start();
}
public stopTracking() {
BackgroundGeolocation.stop();
}
}
I am then injecting this into my page test.ts:
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import {LocationProvider} from '../../providers/location/location';
#Component({
templateUrl: 'build/pages/test/test.html',
})
export class TestPage {
constructor(private nav: NavController, private locationProvider:LocationProvider) {
}
startTracking() {
this.locationProvider.startTracking();
}
stopTracking() {
this.locationProvider.stopTracking();
}
}
My page content is then:
<ion-header>
<ion-navbar>
<button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Test</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<button (click)="startTracking()">
Start Tracking
</button>
<button (click)="stopTracking()">
Stop Tracking
</button>
<ion-item>Latitude / Longitude</ion-item>
<ion-item>
{{locationProvider.latitude}},{{locationProvider.longitude}}
</ion-item>
</ion-content>
When I compile my app for iOS and run in Xcode it looks as I expect, when I click the "Start Tracking" button I see entries in the Xcode console that suggest the location is being obtained correctly i.e.
2016-08-06 12:37:17:370 Test[3264:62403] Better location found: Location: id=0 time=140310177131584 lat=51.8724580445 lon=-2.26443678245263 accu=5 aaccu=-1 speed=-1 head=-1 alt=0 type=current
2016-08-06 12:37:17:371 Test[3264:62403] LocationManager queue Location: id=0 time=140310177131584 lat=51.8724580445 lon=-2.26443678245263 accu=5 aaccu=-1 speed=-1 head=-1 alt=0 type=current
2016-08-06 12:37:18:370 Test[3264:62403] LocationManager didUpdateLocations (operationMode: 1)
2016-08-06 12:37:18:370 Test[3264:62403] Location age 0.001122
2016-08-06 12:37:18:370 Test[3264:62403] Better location found: Location: id=0 time=140310177372752 lat=51.8726980292 lon=-2.26504136905789 accu=5 aaccu=-1 speed=-1 head=-1 alt=0 type=current
2016-08-06 12:37:18:370 Test[3264:62403] LocationManager queue Location: id=0 time=140310177372752 lat=51.8726980292 lon=-2.26504136905789 accu=5 aaccu=-1 speed=-1 head=-1 alt=0 type=current
But the co-ordinates displayed on the page never seem to refresh and update the true location.
Im probably missing the obvious, but can't see it, so any suggestions would be greatly appreciated.
You may have solved this problem by now, but the problem is with this line:
BackgroundGeolocation.configure(config)
.then(this.locationUpdated) <-----
.catch((error) => {
console.log('BackgroundGeolocation error');
});
}
So your callback will get fired, but it will lose the context of this.
You will need to send the correct context of this, by using .bind()
BackgroundGeolocation.configure(config)
.then(this.locationUpdated.bind(this)) <-----
.catch((error) => {
console.log('BackgroundGeolocation error');
});
}

Resources