I'm building an ionic 3 app, and I'm using PouchDB and CouchDB for synchronization.
To create the remote databases, I used the db.info() command as recommended in the official documentation:
note: The remote database will not be created until you do an API call, e.g.: db.info(). The reason behind that is that the PouchDB constructor is completely synchronous, for ease of error handling (i.e. no asynchronous errors).
Here is the code I used in my app:
let remotex = new PouchDB('https://' + auth + '#' + 'xxx.xx:6984/' + xx + '_xx');
return remotex
.info()
.then((res) => {
console.log(res);
return res;
})
.catch(function(err) {
console.log('error : ', err);
return err;
});
This is working fine; the remote databases are created and the sync is working great only when I build my app in the debugging mode:
ionic cordova build android --prod --buildConfig
But, the the remote databases are not created when in the release version:
ionic cordova build android --prod --release --buildConfig
The .info() method is returning:
{"status":0, "name":"unknown"}
Does the command ".info()" work only in debug mode ?
Is there any other method to create the remote databases and make the sync working ?
Thank you.
It turns out that it was a problem related to the SSL certificate that I configured on the CouchDB server. The certificate was self-signed, so when the app is in the debug mode, the cordova build process make it ignoring errors generated by invalid certificates. But this is not the case for release mode.
So I modified the way the app is built in release mode to allow it making "insecure" requests. As I'm building the app for Android, I changed the file
SystemWebViewClient.java located in project/platforms/android/CordovaLib/src/org/apache/cordova/engine/ this way:
if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
// debug = true
handler.proceed();
return;
} else {
// debug = false => comment this
//super.onReceivedSslError(view, handler, error); => comment this
handler.proceed(); // added this
return;
}
This is just a work around and should not be used in production mode.
I found this solution here.
Related
I need to add those to Android files:
android:usesCleartextTraffic="true" and <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
But I'm using managed workflow and I don't know how to add those lines to app.json file.
I did this plugin which seems to work:
const { createRunOncePlugin, withAndroidManifest } = require('#expo/config-plugins');
const withAndroidManifestHavingBetterSecuritySettings = config => {
return withAndroidManifest(config, config => {
const androidManifest = config.modResults.manifest;
const mainApplication = androidManifest.application[0];
if(process.env.CHANNEL !== 'dev') {
androidManifest.$ = {
...androidManifest.$,
'xmlns:tools': 'http://schemas.android.com/tools',
};
mainApplication.$['tools:replace'] = 'android:usesCleartextTraffic';
mainApplication.$['android:usesCleartextTraffic'] = 'false';
}
return config;
});
};
module.exports = createRunOncePlugin(
withAndroidManifestHavingBetterSecuritySettings,
'withAndroidManifestHavingBetterSecuritySettings',
'1.0.0'
);
I had many issues related to merging of AndroidManifest files when "developmentClient": true in my eas.json file (related to me dev eas profile). I believe that it's related to the fact that the debug/AndroidManifest is a higher priority manifest than main/AndroidManifest (not sure though). So my solution was not to ignore the changes when building the dev profile. Hardening security settings in development builds do not seem useful anyhow.
So I struggled with this problem for a while now and the only solution I could come up with was setting the minimum sdk version of the android app from 21 to 28. This is not ideal as my application now does not support old android devices, but doing this defaults the usesClearTextTraffic flag to false.
If your app works fine while developing in expo, but after generating the APK some functions don't work, try this. In my case the APK crashed on login, but building in development with expo was working fine. The problem was that traffic is encrypted so that's why I ended up here trying to set clear text traffic. The problem in my case was with expoPushToken, in the APK it throws an exception I wasn't catching (building with expo worked fine as I said before, no exception). So, if the exception happens just catch it and set the token to empty string.
So, I had this:
import * as Notifications from "expo-notifications";
export async function getDevicePushTokenForAPP() {
const pushToken = await Notifications.getExpoPushTokenAsync();
return pushToken.data;
}
So then, I added the try and catch:
export async function getDevicePushTokenForAPP() {
try {
const pushToken = await Notifications.getExpoPushTokenAsync();
return pushToken.data;
} catch (e) {
return "";
}
}
Now if you build the APK again (expo build:android) it should work fine, in my case login worked. But please note this is for testing purposes only, I needed the APK to quickly show it to the client. (Note that you will need the bundle, not the apk, when uploading to the Playstore). This is a quick fix for you to test the APK; but with no token, push notifications won't work. The final fix is to add firebase to your project, it's mandatory now, so add firebase and with the firebase unique ID, your push notification will work in your APK.
My conclusion is that expo uses its own ID to communicate with firebase, that's why it works while developing but the APK doesn't go through expo and tries to connect to firebase directly, but crashes because there's no ID.
You should update your app.json like that:
"android": {
"usesCleartextTraffic": true,
uses-permission android:name
},
i'm trying to implement Code-Push from AppCenter into my Ionic v4 App. (ref)
I'm stuck on the following Problem: I can update the App, but when i close the App after that and open again it is the old Version again and it says:
Updade ignored, because it was rollbacked
So somehow the update is rolled back after i close the App. After searching for this problem i found that i have to run
this.codePush.notifyApplicationReady()
on application start. I added this to my code, but it doesn't work either. If i run the Application on a Android Emulator and open the Logs, AFTER the Update it says:
cordova_not_available
So it makes sense that the notifyApplicationReady doesn't work, but why is cordova unavailable?
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.codePush.notifyApplicationReady().then(value => {
console.log(value);
});
this.codePush.sync({
deploymentKey: 'MY_KEY',
installMode: InstallMode.IMMEDIATE
}).subscribe(status => {
console.log(status);
});
this.splashScreen.hide();
});
}
Do u use command ionic build --prod ? this conmand will not include cordova.js,so if app installed this package the cordova will not available, in ionic4 i use ionic cordova build android --prod to include the cordova.js and then release the www file to code push serve.it wokrs!
I am trying to call a REST API from Ionic code. The REST API is also developed in my local system. The IP address of my Windows system is say abc.def.gh.i. The GET request API has this URL: http://abc.def.gh.i:8088/check-price/code-001
Problem
I am able call the REST API when I build/run the app using command ionic lab (as this opens up the app on browser). This also works when Ionic code runs on an emulator using the command ionic cordova run android --e78ab88d, as this opens the emulator in same system.
This fails when I run the code on actual Android device by using command ionic cordova run android --device.
Any idea what the issue is?
Here is the provider class that is invoked when an item is passed from the text input:
#Injectable()
export class ServiceProvider {
private urlGetStudentTest: string = "http://abc.def.gh.i:8088/check-price";
callCheckPrice(item) {
console.log("------*****-----" + this.urlcheckprice + '/' + item);
console.log("-----------" + item);
return this.http.get(this.urlcheckprice + '/' + item) .map(res => res.json())
}
}
I can see the two console outputs, after this application stops.
I am using Jenkins to build my android app. i added "Jenkinsfile" in my repo and my current pipeline script looks like this and it is working fine.
node
{
try {
stage("build.clone")
{
checkout scm
}
stage("build.clean")
{
sh "./gradlew clean"
}
stage("build.package")
{
sh "./gradlew assembleDebug"
}
} catch (error) {
throw error
}
}
Now i need to upload my apk to hockeyapp. HockeyApp's Jenkins plugin is installed. And they have made it compatible with pipeline in v 1.2.2
I have googled a lot but found not much help. Kindly guide me or point me to how I can use pipeline script to upload apk to hockeyapp.
Note: I have already created an app on hockey app and I have app token and app id. Also i know curl command is available but i want to use hockeyapp plugin with pipeline
You should be able to get the syntax for just about any Pipeline step via the snippet generator built in to Jenkins.
Doing so in my Jenkins install gives me something like this (horrifying) syntax:
step([$class: 'HockeyappRecorder',
applications: [[downloadAllowed: false, mandatory: false,
notifyTeam: false, releaseNotesMethod: [$class: 'NoReleaseNotes'],
uploadMethod: [$class: 'AppCreation', publicPage: false]]],
debugMode: false, failGracefully: false])
I am new to mobile app development and ionic 2. I get the google authentication working fine for a web app using angularfire2 but that doesn't work on a mobile device (yet?).
I am using ionic 2 version 2.0.0-beta.35 and firebase 3.2.1
Searching led me to the understanding that for the time being I need to use the google+ plugin for cordova, which I have installed.
I am trying this method in my ts code:
loginWithGooglePlugin()
{
return Observable.create(observer =>
{
// note for iOS the googleplus plugin requires ENABLE_BITCODE to be turned off in the Xcode
window.plugins.googleplus.login(
{
'scopes': 'profile email', // optional, space-separated list of scopes, If not included or empty, defaults to `profile` and `email`.
'webClientId': '_google_client_app_id_.apps.googleusercontent.com',
'offline': true, // optional, but requires the webClientId - if set to true the plugin will also return a serverAuthCode, which can be used to grant offline access to a non-Google server
},
function (authData)
{
console.log('got google auth data:', JSON.stringify(authData, null, 2));
let provider = firebase.auth.GoogleAuthProvider.credential(authData.idToken, authData.accessToken);
firebase.auth().signInWithCredential(provider).then((success) =>
{
console.log('success!', JSON.stringify(success, null, 2));
observer.next(success);
}, (error) =>
{
console.log('error', JSON.stringify(error, null, 2))
});
},
function (msg)
{
this.error = msg;
}
);
});
}
But the compiler keeps complaining about two things:
1. window.plugins is unknown. How can I convince ts that it's there?
There is no credential on the GoogleAuthProvider object. Searching yielded this link: firebase docs which says there was a method getCredential, which is not recognized either.
My typings seem to be fine. GoogleAuthProvider itself is recognized.
How can I fix this?
Actually, this is a bug in the typescript definitions. The Firebase team has been notified and is working on a fix. In the meantime use the following workaround:
(<any> firebase.auth.GoogleAuthProvider).credential
In my Ionic2 RC1 + Firebase3.5 + AngularFire2.beta5 project I had the same problem... Google Auth with Popup worked in Browser but not in my Android .APK
Firstly, I add 192.168.1.172 to my Firebase Console authorized domain list and <allow-navigation href="http://192.168.1.172:8100"/> to my config.xml.
After this, I found that installing Cordova InAppBrowser plugin solves my problem definitively.
I didn't need to modify my code, only plug and play, exactly like David East says in his Social login with Ionic blog.