Related
I'd like to ask for some help with an Android issue my team is having with our Signed Build (.apk/.aab).
TL/DR:
The issue is that when we run our app locally un debug mode using ionic serve or Android Studio, we are able to login fine. But when we "Generate a Signed Bundle/APK" the app via a java keystone, we are unable to login. It seem the login process cannot find the AuthToken on the phone, and so just quits.
Details:
We have a mobile app built using ionic 5/Angular 8. We are using the AuthConnect Enterprise plugin as well ("#ionic-enterprise/auth": "^3.9.2").
We are using Android studio (2021.1 Patch 1).
Package.json (Below)
{
"name": "xxx",
"description": "xxx xxxxxxxx Mobile Version",
"version": "0.0.2",
"author": "support#xxxx.app",
"homepage": "https://www.xxxx.app",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"postinstall": "npx jetifier"
},
"private": true,
"dependencies": {
"#angular/common": "~8.2.14",
"#angular/core": "~8.2.14",
"#angular/fire": "^5.4.2",
"#angular/forms": "~8.2.14",
"#angular/platform-browser": "~8.2.14",
"#angular/platform-browser-dynamic": "~8.2.14",
"#angular/router": "~8.2.14",
"#googlemaps/js-api-loader": "^1.12.9",
"#ionic-enterprise/auth": "^3.9.2",
"#ionic-enterprise/camera": "^6.0.0",
"#ionic-enterprise/geolocation": "^4.1.0",
"#ionic-enterprise/inappbrowser": "^5.0.1",
"#ionic-native/camera": "^5.36.0",
"#ionic-native/core": "^5.25.0",
"#ionic-native/document-viewer": "^5.31.1",
"#ionic-native/file": "^5.25.0",
"#ionic-native/file-opener": "^5.25.0",
"#ionic-native/geolocation": "^5.36.0",
"#ionic-native/google-analytics": "^5.25.0",
"#ionic-native/google-maps": "^5.5.0",
"#ionic-native/http": "^5.27.0",
"#ionic-native/local-notifications": "^5.36.0",
"#ionic-native/native-geocoder": "^5.36.0",
"#ionic-native/network": "^5.36.0",
"#ionic-native/open-native-settings": "^5.36.0",
"#ionic-native/splash-screen": "^5.25.0",
"#ionic-native/status-bar": "^5.25.0",
"#ionic/angular": "^5.1.0",
"#ionic/storage": "^2.3.1",
"#types/google.maps": "^3.46.1",
"capacitor-pdf-viewer-plugin": "^1.0.0",
"cordova-plugin-add-swift-support": "^2.0.2",
"cordova-plugin-advanced-http": "^3.0.0",
"cordova-plugin-androidx-adapter": "^1.1.3",
"cordova-plugin-buildinfo": "^4.0.0",
"cordova-plugin-device": "2.0.2",
"cordova-plugin-document-viewer": "^1.0.0",
"cordova-plugin-file": "^6.0.2",
"cordova-plugin-geolocation": "^4.0.2",
"cordova-plugin-google-analytics": "^1.9.0",
"cordova-plugin-ionic-keyboard": "^2.0.5",
"cordova-plugin-ionic-webview": "^5.0.0",
"cordova-plugin-local-notification": "^0.9.0-beta.2",
"cordova-plugin-nativegeocoder": "^3.4.1",
"cordova-plugin-network-information": "^2.0.2",
"cordova-plugin-splashscreen": "5.0.2",
"cordova-plugin-statusbar": "2.4.2",
"cordova-sqlite-storage": "^6.0.0",
"core-js": "^2.5.4",
"d3-hierarchy": "^1.1.9",
"file": "^0.2.2",
"firebase": "^7.14.3",
"hawk": "^7.0.10",
"jetifier": "^2.0.0",
"jquery": "^3.5.1",
"jquery-sparkline": "^2.4.0",
"moment": "^2.25.3",
"ngx-ionic-image-viewer": "^0.7.0",
"ngx-logger": "^4.1.9",
"rollbar": "^2.15.2",
"rxjs": "^6.5.5",
"tslib": "^1.11.2",
"zone.js": "~0.9.1"
},
"devDependencies": {
"#angular-devkit/architect": "~0.803.2",
"#angular-devkit/build-angular": "~0.803.2",
"#angular-devkit/core": "~8.3.23",
"#angular-devkit/schematics": "~8.3.23",
"#angular/cli": "8.3.23",
"#angular/compiler": "~8.2.14",
"#angular/compiler-cli": "~8.2.14",
"#angular/language-service": "~8.2.14",
"#ionic/angular-toolkit": "^2.2.0",
"#types/googlemaps": "^3.43.3",
"#types/jasmine": "~3.3.8",
"#types/jasminewd2": "~2.0.3",
"#types/jquery": "^3.3.38",
"#types/node": "~8.9.4",
"codelyzer": "^5.2.2",
"cordova-android": "^10.0.0",
"cordova-ios": "^6.2.0",
"cordova-open-native-settings": "^1.5.5",
"cordova-plugin-camera": "git+https://github.com/apache/cordova-plugin-camera.git",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.5.3",
"protractor": "^5.4.4",
"ts-node": "~7.0.0",
"tslint": "~5.15.0",
"typescript": "~3.4.3"
},
"cordova": {
"plugins": {
"cordova-plugin-file": {},
"cordova-plugin-geolocation": {},
"cordova-plugin-network-information": {},
"cordova-plugin-google-analytics": {
"GMS_VERSION": "11.0.1"
},
"cordova-plugin-statusbar": {},
"cordova-plugin-device": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-keyboard": {},
"cordova-plugin-buildinfo": {},
"cordova-plugin-advanced-http": {},
"#ionic-enterprise/auth": {
"AUTH_URL_SCHEME": "com.response.app",
"OKHTTP_VERSION": "3.10.0"
},
"cordova-plugin-document-viewer": {},
"cordova-plugin-googlemaps": {
"LOCATION_WHEN_IN_USE_DESCRIPTION": "This app wants to get your location while this app runs only.",
"LOCATION_ALWAYS_USAGE_DESCRIPTION": "This app wants to get your location always, even this app runs in background."
},
"cordova-plugin-file-opener2": {
"ANDROID_SUPPORT_V4_VERSION": "27.+"
},
"cordova-plugin-ionic-webview": {},
"#ionic-enterprise/inappbrowser": {},
"cordova-sqlite-storage": {},
"cordova-plugin-camera": {
"ANDROIDX_CORE_VERSION": "1.6.+"
},
"cordova-plugin-file-transfer": {},
"cordova-plugin-nativegeocoder": {
"LOCATION_WHEN_IN_USE_DESCRIPTION": "Use geocoder service"
},
"cordova-open-native-settings": {}
},
"platforms": [
"ios",
"android"
]
}
}
I am also attaching our config.xml file
<?xml version='1.0' encoding='utf-8'?>
<widget android-versionCode="1" id="app.response" ios-CFBundleVersion="1" version="3.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>xxxx</name>
<description>xxxx.app Mobile Application</description>
<author email="support#reponse.app" href="https://response.app">xxxx Development Support Team</author>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="https://firebasestorage.googleapis.com/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<preference name="ScrollEnabled" value="false" />
<preference name="android-minSdkVersion" value="22" />
<preference name="android-compileSdkVersion" value="30" />
<preference name="android-targetSdkVersion" value="30" />
<preference name="BackupWebStorage" value="none" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="FadeSplashScreenDuration" value="300" />
<preference name="SplashShowOnlyFirstTime" value="false" />
<preference name="SplashScreen" value="screen" />
<preference name="SplashScreenDelay" value="3000" />
<preference name="AndroidXEnabled" value="true" />
<preference name="WKWebViewOnly" value="true" />
<preference name="GOOGLE_MAPS_ANDROID_API_KEY" value="AIzaSyAm2VD_ypzfNZ1muaUirSXtOsplMft6O-0" />
<preference name="GOOGLE_MAPS_IOS_API_KEY" value="AIzaSyBoWBCEoKbAXNffdYfC8-0nZcrHgIfxEH0" />
<preference name="hostname" value="localhost" />
<preference name="AndroidInsecureFileModeEnabled" value="true" />
<platform name="android">
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
<application android:usesCleartextTraffic="true" />
<application android:networkSecurityConfig="#xml/network_security_config" />
</edit-config>
<resource-file src="resources/android/xml/network_security_config.xml" target="app/src/main/res/xml/network_security_config.xml" />
<allow-intent href="market:*" />
<preference name="loadUrlTimeoutValue" value="700000" />
<preference name="SplashScreenDelay" value="3000" />
</platform>
<platform name="ios">
<edit-config file="*-Info.plist" mode="merge" target="NSCameraUsageDescription">
<string>Camera usage needs to be enabled on the device in order to upload photos of an incident.</string>
</edit-config>
<edit-config file="*-Info.plist" mode="merge" target="NSPhotoLibraryAddUsageDescription">
<string>Required to access the user’s photo library.</string>
</edit-config>
<edit-config file="*-Info.plist" mode="merge" target="NSPhotoLibraryUsageDescription">
<string>Required to access the user’s photo library (iOS 14+).</string>
</edit-config>
<edit-config file="*-Info.plist" mode="merge" target="NSLocationWhenInUseUsageDescription">
<string>Location/GPS services are required in order to pinpoint your location on the map during an incident.</string>
</edit-config>
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<plugin name="cordova-plugin-statusbar" spec="2.4.2" />
<plugin name="cordova-plugin-device" spec="2.0.2" />
<plugin name="cordova-plugin-splashscreen" spec="5.0.2" />
<plugin name="cordova-plugin-ionic-keyboard" spec="^2.0.5" />
<plugin name="cordova-sqlite-storage" spec="^6.0.0" />
<plugin name="cordova-plugin-network-information" spec="^2.0.2" />
<plugin name="cordova-plugin-file" spec="^6.0.2" />
<plugin name="cordova-plugin-geolocation" spec="^4.0.2" />
</widget>
What could be going wrong?
Update: I managed to figure out the issue. We identified that our authentication API was not being hit. This lead us to look at the Resources/android/xml/network_security_config.xml file.
I found this link very helpful:
https://developer.android.com/training/articles/security-config
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system"/>
</trust-anchors>
</base-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">localhost</domain>
<domain includeSubdomains="true">http://xxxx-prod.xxxx.com</domain>
</domain-config>
<debug-overrides>
<trust-anchors>
<certificates src="system"/>
</trust-anchors>
</debug-overrides>
</network-security-config>
I have an issue with my Ionic app. The issue is very strange when I create a build from ionic dashboard and installed it in my device everything is working fine but if I am restarting the device or killing app from background and then I am opening the app is reflecting me old content. Like old UI screens.
I did following thing to resolve it.
Run ionic platform remove android then ionic platform add android
Run cordova clean
But these are not working for me.
config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example" version="1.0.21" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>App Name </name>
<description>App Name</description>
<author email="hi#ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>
<content src="index.html" />
<allow-navigation href="*" />
<allow-intent href="*" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<preference name="webviewbounce" value="false" />
<preference name="UIWebViewBounce" value="false" />
<preference name="DisallowOverscroll" value="true" />
<preference name="android-minSdkVersion" value="16" />
<preference name="BackupWebStorage" value="none" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="SplashScreenDelay" value="0" />
<preference name="loadUrlTimeoutValue" value="60000" />
<preference name="android-windowSoftInputMode" value="adjustResize" />
<preference name="SplashScreen" value="screen" />
<preference name="AutoHideSplashScreen" value="true" />
<preference name="FadeSplashScreenDuration" value="300" />
<preference name="SplashShowOnlyFirstTime" value="true" />
<preference name="ShowSplashScreenSpinner" value="true" />
<preference name="FadeSplashScreen" value="true" />
<preference name="UseSwiftLanguageVersion" value="4.2" />
<platform name="android">
<allow-intent href="market:*" />
<preference name="android-targetSdkVersion" value="28" />
<icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
</platform>
<platform name="ios">
<edit-config file="*-Info.plist" mode="merge" target="NSCameraUsageDescription">
<string>To scan barcodes</string>
</edit-config>
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<plugin name="cordova-plugin-device" spec="1.1.4" />
<plugin name="cordova-plugin-statusbar" spec="2.2.2" />
<plugin name="cordova-plugin-sslcertificatechecker" spec="5.1.0" />
<plugin name="cordova-plugin-certificates" spec="^0.6.4" />
<plugin name="cordova-plugin-http" spec="1.2.0" />
<plugin name="cordova-plugin-file" spec="^6.0.1" />
<plugin name="cordova-plugin-splashscreen" spec="^4.0.0" />
<plugin name="cordova-plugin-ionic" spec="^2.0.4">
<variable name="APP_ID" value="e363211c" />
<variable name="CHANNEL_NAME" value="Production" />
<variable name="UPDATE_METHOD" value="background" />
<variable name="UPDATE_API" value="https://api.ionicjs.com" />
<variable name="MAX_STORE" value="2" />
</plugin>
<plugin name="ionic-plugin-keyboard" spec="^2.2.1" />
<plugin name="cordova-plugin-x-socialsharing" spec="^5.4.0" />
<plugin name="cordova-plugin-whitelist" spec="1.3.3" />
<plugin name="cordova-plugin-datepicker" spec="0.9.3" />
<allow-navigation href="http://192.168.2.26:8100" />
<engine name="ios" spec="5.0.0" />
<engine name="android" spec="6.3.0" />
<engine name="browser" spec="5.0.4" />
package.json
{
"name": "App Name ",
"version": "1.0.21",
"author": "Ionic Framework",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
"preinstall": "./cordovaOverride.sh",
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build --prod",
"lint": "ionic-app-scripts lint",
"ionic:serve": "ionic-app-scripts serve"
},
"config": {
"ionic_source_map": "source_map"
},
"dependencies": {
"#angular/common": "4.1.3",
"#angular/compiler": "4.1.3",
"#angular/compiler-cli": "4.1.3",
"#angular/core": "4.1.3",
"#angular/forms": "4.1.3",
"#angular/http": "4.1.3",
"#angular/platform-browser": "4.1.3",
"#angular/platform-browser-dynamic": "4.1.3",
"#ionic-native/app-preferences": "4.7.0",
"#ionic-native/barcode-scanner": "4.7.0",
"#ionic-native/core": "4.7.0",
"#ionic-native/date-picker": "4.7.0",
"#ionic-native/file": "4.7.0",
"#ionic-native/printer": "4.7.0",
"#ionic-native/social-sharing": "4.7.0",
"#ionic-native/splash-screen": "4.7.0",
"#ionic-native/sqlite": "4.7.0",
"#ionic-native/status-bar": "4.7.0",
"#ionic/pro": "1.0.16",
"#ionic/storage": "2.1.3",
"#zxing/library": "0.5.0",
"amazon-cognito-identity-js": "1.26.0",
"angular2-signaturepad": "2.6.1",
"aws-sdk": "2.156.0",
"cordova-android": "6.3.0",
"cordova-browser": "5.0.4",
"cordova-ios": "5.0.0",
"cordova-pdf-generator": "^2.0.8",
"cordova-plugin-add-swift-support": "^1.7.2",
"cordova-plugin-android-permissions": "^1.0.2",
"cordova-plugin-barcodescanner-browser-support": "7.1.22",
"cordova-plugin-certificates": "^0.6.4",
"cordova-plugin-datepicker": "^0.9.3",
"cordova-plugin-device": "^1.1.7",
"cordova-plugin-file": "^6.0.2",
"cordova-plugin-http": "^1.2.0",
"cordova-plugin-ionic": "^2.0.4",
"cordova-plugin-printer": "^0.7.3",
"cordova-plugin-splashscreen": "^4.1.0",
"cordova-plugin-sslcertificatechecker": "^5.1.0",
"cordova-plugin-statusbar": "^2.4.3",
"cordova-plugin-whitelist": "^1.3.3",
"cordova-plugin-x-socialsharing": "^5.6.2",
"es6-promise-plugin": "^4.2.2",
"eslint-plugin-html": "2.0.1",
"ionic-angular": "3.9.2",
"ionic-plugin-keyboard": "^2.2.1",
"ionicons": "3.0.0",
"moment": "^2.24.0",
"node-sass": "^4.9.4",
"phonegap-plugin-barcodescanner": "^7.1.2",
"rxjs": "5.4.2",
"sw-toolbox": "3.6.0",
"zone.js": "0.8.12"
},
"devDependencies": {
"#ionic/app-scripts": "3.2.3",
"#types/node": "8.5.1",
"json-loader": "0.5.7",
"typescript": "2.3.4",
"webpack": "3.8.1"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-plugin-device": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-android-permissions": {},
"cordova-plugin-sslcertificatechecker": {},
"cordova-plugin-certificates": {},
"cordova-plugin-http": {},
"cordova-plugin-file": {},
"cordova-pdf-generator": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic": {
"APP_ID": "e363211c",
"CHANNEL_NAME": "Production",
"UPDATE_METHOD": "background",
"UPDATE_API": "https://api.ionicjs.com",
"MAX_STORE": "2"
},
"ionic-plugin-keyboard": {},
"cordova-plugin-x-socialsharing": {
"ANDROID_SUPPORT_V4_VERSION": "24.1.1+"
},
"cordova-plugin-printer": {},
"phonegap-plugin-barcodescanner": {
"ANDROID_SUPPORT_V4_VERSION": "27.+"
},
"cordova-plugin-whitelist": {},
"cordova-plugin-datepicker": {}
},
"platforms": [
"ios",
"android",
"browser"
]
}
}
In your config.xml and package.json try to change "UPDATE_METHOD": "background" to "UPDATE_METHOD": "none"
After RND I found that its the problem of ionic dashboard.
Ionic dashboard has channels.We add our git commit on channel to update ionic app.
Here is the details.
<plugin name="cordova-plugin-ionic" spec="^2.0.4">
<variable name="APP_ID" value="e363211c" />
<variable name="CHANNEL_NAME" value="Production" />
<variable name="UPDATE_METHOD" value="background" />
<variable name="UPDATE_API" value="https://api.ionicjs.com" />
<variable name="MAX_STORE" value="2" />
</plugin>
In my ionic dashboard 'Production' channel had a old version commit thats why when app is update from ionic dashboard in background it took old version old.
for fixing this issue I add new commit with production channel and app works fine.
I am creating a login screen in Ionic. The problem is that when I click on the input field to open the Keyboard, it's not opening.
Then I click outside on the input field and then click on the input field then the keyboard is visible OR I click on the input fields 3 to 4 times and after that the Keyboard is visible.
I want to open the keyboard when I click on the input field for the first time. I've implemented the focusing code but it is not working. Does anyone have any suggestions?
Here is the code
config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example" version="1.0.21" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>App Name </name>
<description>App Name</description>
<author email="hi#ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>
<content src="index.html" />
<allow-navigation href="*" />
<allow-intent href="*" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<preference name="webviewbounce" value="false" />
<preference name="UIWebViewBounce" value="false" />
<preference name="DisallowOverscroll" value="true" />
<preference name="android-minSdkVersion" value="16" />
<preference name="BackupWebStorage" value="none" />
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="SplashScreenDelay" value="0" />
<preference name="loadUrlTimeoutValue" value="60000" />
<preference name="android-windowSoftInputMode" value="adjustResize" />
<preference name="SplashScreen" value="screen" />
<preference name="AutoHideSplashScreen" value="true" />
<preference name="FadeSplashScreenDuration" value="300" />
<preference name="SplashShowOnlyFirstTime" value="true" />
<preference name="ShowSplashScreenSpinner" value="true" />
<preference name="FadeSplashScreen" value="true" />
<preference name="UseSwiftLanguageVersion" value="4.2" />
<platform name="android">
<allow-intent href="market:*" />
<preference name="android-targetSdkVersion" value="28" />
<icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
</platform>
<platform name="ios">
<edit-config file="*-Info.plist" mode="merge" target="NSCameraUsageDescription">
<string>To scan barcodes</string>
</edit-config>
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<plugin name="cordova-plugin-device" spec="1.1.4" />
<plugin name="cordova-plugin-statusbar" spec="2.2.2" />
<plugin name="cordova-plugin-sslcertificatechecker" spec="5.1.0" />
<plugin name="cordova-plugin-certificates" spec="^0.6.4" />
<plugin name="cordova-plugin-http" spec="1.2.0" />
<plugin name="cordova-plugin-file" spec="^6.0.1" />
<plugin name="cordova-plugin-splashscreen" spec="^4.0.0" />
<plugin name="cordova-plugin-ionic" spec="^2.0.4">
<variable name="APP_ID" value="e363211c" />
<variable name="CHANNEL_NAME" value="Production" />
<variable name="UPDATE_METHOD" value="background" />
<variable name="UPDATE_API" value="https://api.ionicjs.com" />
<variable name="MAX_STORE" value="2" />
</plugin>
<plugin name="ionic-plugin-keyboard" spec="^2.2.1" />
<plugin name="cordova-plugin-x-socialsharing" spec="^5.4.0" />
<plugin name="cordova-plugin-whitelist" spec="1.3.3" />
<plugin name="cordova-plugin-datepicker" spec="0.9.3" />
<allow-navigation href="http://192.168.2.26:8100" />
<engine name="ios" spec="5.0.0" />
<engine name="android" spec="6.3.0" />
<engine name="browser" spec="5.0.4" />
</widget>
Package.json
{
"name": "App Name ",
"version": "1.0.21",
"author": "Ionic Framework",
"homepage": "http://ionicframework.com/",
"private": true,
"scripts": {
"preinstall": "./cordovaOverride.sh",
"clean": "ionic-app-scripts clean",
"build": "ionic-app-scripts build --prod",
"lint": "ionic-app-scripts lint",
"ionic:serve": "ionic-app-scripts serve"
},
"config": {
"ionic_source_map": "source_map"
},
"dependencies": {
"#angular/common": "4.1.3",
"#angular/compiler": "4.1.3",
"#angular/compiler-cli": "4.1.3",
"#angular/core": "4.1.3",
"#angular/forms": "4.1.3",
"#angular/http": "4.1.3",
"#angular/platform-browser": "4.1.3",
"#angular/platform-browser-dynamic": "4.1.3",
"#ionic-native/app-preferences": "4.7.0",
"#ionic-native/barcode-scanner": "4.7.0",
"#ionic-native/core": "4.7.0",
"#ionic-native/date-picker": "4.7.0",
"#ionic-native/file": "4.7.0",
"#ionic-native/printer": "4.7.0",
"#ionic-native/social-sharing": "4.7.0",
"#ionic-native/splash-screen": "4.7.0",
"#ionic-native/sqlite": "4.7.0",
"#ionic-native/status-bar": "4.7.0",
"#ionic/pro": "1.0.16",
"#ionic/storage": "2.1.3",
"#zxing/library": "0.5.0",
"amazon-cognito-identity-js": "1.26.0",
"angular2-signaturepad": "2.6.1",
"aws-sdk": "2.156.0",
"cordova-android": "6.3.0",
"cordova-browser": "5.0.4",
"cordova-ios": "5.0.0",
"cordova-pdf-generator": "^2.0.8",
"cordova-plugin-add-swift-support": "^1.7.2",
"cordova-plugin-android-permissions": "^1.0.2",
"cordova-plugin-barcodescanner-browser-support": "7.1.22",
"cordova-plugin-certificates": "^0.6.4",
"cordova-plugin-datepicker": "^0.9.3",
"cordova-plugin-device": "^1.1.7",
"cordova-plugin-file": "^6.0.2",
"cordova-plugin-http": "^1.2.0",
"cordova-plugin-ionic": "^2.0.4",
"cordova-plugin-printer": "^0.7.3",
"cordova-plugin-splashscreen": "^4.1.0",
"cordova-plugin-sslcertificatechecker": "^5.1.0",
"cordova-plugin-statusbar": "^2.4.3",
"cordova-plugin-whitelist": "^1.3.3",
"cordova-plugin-x-socialsharing": "^5.6.2",
"es6-promise-plugin": "^4.2.2",
"eslint-plugin-html": "2.0.1",
"ionic-angular": "3.9.2",
"ionic-plugin-keyboard": "^2.2.1",
"ionicons": "3.0.0",
"moment": "^2.24.0",
"node-sass": "^4.9.4",
"phonegap-plugin-barcodescanner": "^7.1.2",
"rxjs": "5.4.2",
"sw-toolbox": "3.6.0",
"zone.js": "0.8.12"
},
"devDependencies": {
"#ionic/app-scripts": "3.2.3",
"#types/node": "8.5.1",
"json-loader": "0.5.7",
"typescript": "2.3.4",
"webpack": "3.8.1"
},
"description": "An Ionic project",
"cordova": {
"plugins": {
"cordova-plugin-device": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-android-permissions": {},
"cordova-plugin-sslcertificatechecker": {},
"cordova-plugin-certificates": {},
"cordova-plugin-http": {},
"cordova-plugin-file": {},
"cordova-pdf-generator": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic": {
"APP_ID": "e363211c",
"CHANNEL_NAME": "Production",
"UPDATE_METHOD": "background",
"UPDATE_API": "https://api.ionicjs.com",
"MAX_STORE": "2"
},
"ionic-plugin-keyboard": {},
"cordova-plugin-x-socialsharing": {
"ANDROID_SUPPORT_V4_VERSION": "24.1.1+"
},
"cordova-plugin-printer": {},
"phonegap-plugin-barcodescanner": {
"ANDROID_SUPPORT_V4_VERSION": "27.+"
},
"cordova-plugin-whitelist": {},
"cordova-plugin-datepicker": {}
},
"platforms": [
"ios",
"android",
"browser"
]
}
}
login.html
<!-- Page content inputs -->
<ion-content padding class="background">
<ion-list>
<!-- logo on top of page -->
<ion-item no-lines justify-content-center align-items-center>
<ion-row justify-content-center align-items-center>
<ion-col>
<div style="text-align: center">
<img align='center' src="assets/icon/logo.png" height="140px" width="180px">
</div>
</ion-col>
</ion-row>
</ion-item>
<ion-item no-lines
style="height:40px; user-select: auto; padding-right:16px;border-style: solid; border-width: 1px;border-radius:3px;border-color: #E3e3e3">
<ion-label color="dark" item-left>
<ion-icon name="md-mail"></ion-icon>
</ion-label>
<ion-input style="user-select: auto" class="text_style" type="email" placeholder="Email"
[(ngModel)]="userEmail" name="userEmail"></ion-input>
</ion-item>
<!-- Password Field with show/hide option controls-->
<ion-item no-lines
style=" user-select: auto; padding-right:16px; border-style: solid; border-width: 1px;border-radius:3px;border-color: #E3e3e3">
<ion-label color="dark" item-left>
<ion-icon name="md-lock"></ion-icon>
</ion-label>
<ion-input style="user-select: auto" class="ion-input" [(ngModel)]="password" type="{{type}}"
placeholder="Password" name="password"></ion-input>
<button class="ion-input-button" *ngIf="!showPass" ion-button clear color="dark" type="button" item-right
(click)="showPassword()">
<ion-icon name="md-eye-off"></ion-icon>
</button>
<button class="ion-input-button" *ngIf="showPass" ion-button clear color="dark" type="button" item-right
(click)="showPassword()">
<ion-icon name="md-eye"></ion-icon>
</button>
</ion-item>
<!--Forgot Password Link -->
<ion-row>
<ion-col>
<!-- <ion-item> -->
<ion-row>
<ion-checkbox [(ngModel)]="rememberLogin" (ionChange)="keepMeLogin()"
style="margin-top:13px; margin-right:5px; margin-left:16px"></ion-checkbox>
<ion-label style="text-align:left; font-size: 12px; padding-top:4px">Remember Me</ion-label>
</ion-row>
</ion-col>
<ion-col>
<button ion-button clear color="button-color" style="text-align:right; font-size: 12px"
(click)="forgotPassword()" float-right>Forgot Password
</button>
</ion-col>
</ion-row>
<!--Login Button -->
<button style="height:48px" ion-button full color="button-color" (click)="onLogin()">Log in</button>
</ion-list>
<!-- </ion-card-content>
</ion-card> -->
<!-- Create New Account Link -->
</ion-content>
<!--End content -->
I have a SmartField that I would like to connect to a ODATA service to get valueHelp for free.
The model, that points to the ODATA service looks as following:
"EAMMALFUNCTION": {
"uri": "/sap/opu/odata/sap/EAM_MALFUNCTION_MANAGE/",
"type": "sap.ui.model.odata.v2.ODataModel",
"settings": {
"defaultOperationMode": "Server",
"defaultBindingMode": "OneWay",
"defaultCountMode": "Request"
},
"dataSource": "EAM_MALFUNCTION_MANAGE",
"preload": true
}
And the uri to the entityset is /sap/opu/odata/sap/EAM_MALFUNCTION_MANAGE/I_PMContactCardEmployee and meta definition is:
<EntitySet Name="I_PMContactCardEmployee" EntityType="EAM_MALFUNCTION_MANAGE.I_PMContactCardEmployeeType" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:searchable="true" sap:content-version="1"/>
<EntityType Name="I_PMContactCardEmployeeType" sap:label="Mitarbeiter" sap:content-version="1">
<Key>
<PropertyRef Name="PersonnelNumber"/>
</Key>
<Property Name="PersonnelNumber" Type="Edm.String" Nullable="false" MaxLength="8" sap:display-format="NonNegative" sap:text="EmployeeFullName" sap:label="Personalnummer"/>
<Property Name="EmployeeFullName" Type="Edm.String" MaxLength="80" sap:label="Vollständiger Name" sap:filterable="false"/>
<Property Name="FirstName" Type="Edm.String" MaxLength="40" sap:label="Vorname" sap:quickinfo="Vorname des Geschäftspartners (Person)"/>
<Property Name="FamilyName" Type="Edm.String" MaxLength="40" sap:label="Nachname" sap:quickinfo="Nachname des Geschäftspartners (Person)"/>
<Property Name="Job" Type="Edm.String" MaxLength="8" sap:display-format="NonNegative" sap:label="Stellenschlüssel" sap:quickinfo="Stelle" sap:filterable="false"/>
<Property Name="JobName" Type="Edm.String" MaxLength="25" sap:label="Stellenbezeichnung" sap:filterable="false"/>
<Property Name="CompanyCode" Type="Edm.String" MaxLength="4" sap:display-format="UpperCase" sap:text="CompanyCodeName" sap:label="Buchungskreis"/>
<Property Name="CompanyCodeName" Type="Edm.String" MaxLength="25" sap:label="Name der Firma" sap:quickinfo="Buchungskreis- oder Firmen-Bezeichnung" sap:filterable="false"/>
<Property Name="OrganizationalUnit" Type="Edm.String" MaxLength="8" sap:display-format="NonNegative" sap:label="Organisationseinheit"/>
<Property Name="OrganizationalUnitName" Type="Edm.String" MaxLength="25" sap:label="OrgEinheitenkurztext" sap:quickinfo="Organisationseinheitenkurztext" sap:filterable="false"/>
<Property Name="PhoneNumber" Type="Edm.String" MaxLength="30" sap:display-format="UpperCase" sap:label="Telefon" sap:quickinfo="Telefonnummer: Vorwahl+Anschluß" sap:filterable="false"/>
<Property Name="NormalizedPhoneNumber" Type="Edm.String" MaxLength="30" sap:display-format="UpperCase" sap:label="Telefonnummer" sap:quickinfo="Vollständige Nummer: Vorwahl+Anschluß+Durchwahl" sap:filterable="false"/>
<Property Name="MobilePhoneNumber" Type="Edm.String" MaxLength="30" sap:display-format="UpperCase" sap:label="Telefon" sap:quickinfo="Telefonnummer: Vorwahl+Anschluß" sap:filterable="false"/>
<Property Name="MblNormalizedPhoneNumber" Type="Edm.String" MaxLength="30" sap:display-format="UpperCase" sap:label="Telefonnummer" sap:quickinfo="Vollständige Nummer: Vorwahl+Anschluß+Durchwahl" sap:filterable="false"/>
<Property Name="DefaultEmailAddress" Type="Edm.String" MaxLength="241" sap:label="E-Mail-Adresse"/>
<Property Name="UserID" Type="Edm.String" MaxLength="12" sap:display-format="UpperCase" sap:label="Benutzer-ID" sap:filterable="false"/>
</EntityType>
supplies the following data:
{
"d": {
"results": [
{
"__metadata": {
"id": "https://example:4000/sap/opu/odata/sap/EAM_MALFUNCTION_MANAGE/I_PMContactCardEmployee('00000019')",
"uri": "https://example:4000/sap/opu/odata/sap/EAM_MALFUNCTION_MANAGE/I_PMContactCardEmployee('00000019')",
"type": "EAM_MALFUNCTION_MANAGE.I_PMContactCardEmployeeType"
},
"PersonnelNumber": "00000019",
"EmployeeFullName": "Test Normi_20180206",
"FirstName": "Normi_20180206",
"FamilyName": "Test",
"Job": "00000000",
"JobName": "",
"CompanyCode": "CH01",
"CompanyCodeName": "Country Template CH",
"OrganizationalUnit": "50000066",
"OrganizationalUnitName": "",
"PhoneNumber": "",
"NormalizedPhoneNumber": "",
"MobilePhoneNumber": "",
"MblNormalizedPhoneNumber": "",
"DefaultEmailAddress": "",
"UserID": ""
},
{
"__metadata": {
"id": "https://example:4000/sap/opu/odata/sap/EAM_MALFUNCTION_MANAGE/I_PMContactCardEmployee('00000014')",
"uri": "https://example:4000/sap/opu/odata/sap/EAM_MALFUNCTION_MANAGE/I_PMContactCardEmployee('00000014')",
"type": "EAM_MALFUNCTION_MANAGE.I_PMContactCardEmployeeType"
},
"PersonnelNumber": "00000014",
"EmployeeFullName": "TEST Einchäuferli",
"FirstName": "Einchäuferli",
"FamilyName": "TEST",
"Job": "00000000",
"JobName": "",
"CompanyCode": "CH01",
"CompanyCodeName": "Country Template CH",
"OrganizationalUnit": "50000055",
"OrganizationalUnitName": "",
"PhoneNumber": "",
"NormalizedPhoneNumber": "",
"MobilePhoneNumber": "",
"MblNormalizedPhoneNumber": "",
"DefaultEmailAddress": "",
"UserID": "M4711"
},
What am I trying to archive is, to connect the SmartField with the ODATA service and get valueHelp for free without any specific coding for value help.
When I select a value on the value help, then it should insert the PersonnelNumber into the SmartField.
The I_PMContactCardEmployee is a CDS consumption view and it provides an interface to search help:
#AbapCatalog.sqlViewName: 'IPMCONTCARDEMP'
#AbapCatalog.compiler.compareFilter: true
#AccessControl.authorizationCheck: #CHECK
#VDM.viewType: #COMPOSITE
#EndUserText.label: 'Employee'
#ObjectModel.representativeKey : 'PersonnelNumber'
#Search.searchable: true
#ClientHandling.algorithm: #SESSION_VARIABLE
#ObjectModel.usageType.dataClass: #MASTER
#ObjectModel.usageType.serviceQuality: #D
#ObjectModel.usageType.sizeCategory: #L
#AccessControl.personalData.blocking: #REQUIRED
define view I_PMContactCardEmployee
I already tried to connect the SmartField with the I_PMContactCardEmployee service as following:
<smartField:SmartLabel labelFor="pmAssignTo" />
<smartfield:SmartField id="pmAssignTo" binding="{EAMMALFUNCTION>/I_PMContactCardEmployee}" value="{PersonnelNumber}">
<layoutData>
<layout:GridData span="L7 M7 S12"/>
</layoutData>
</smartfield:SmartField>
and I've got the error message:
Uncaught (in promise) Error: Cannot add direct child without default aggregation defined for control sap.ui.comp.smartfield.SmartField
I have these emails : "jack#gmail.com", "jack1#gmail.com".
I want to sort them
The Solr will return the following result:
jack1#gmail.com
jack#gmail.com
I think the correct sort result should be:
jack#gmail.com
jack1#gmail.com
The configuration like this:
<field name="email" type="string" indexed="true" stored="true"/>
Anyone could help?
The following is solr response:
{ "responseHeader":{ "status":0, "QTime":0, "params":{ "sort":"advertiser_email_t asc", "indent":"true", "q":":", "wt":"json", "response":{"numFound":3,"start":0,"docs":[ { "advertiser_email_t":"ad111#qq.com", "id":"01df4dea-beb3-46fb-940b-78eda109503c" }, { "advertiser_email_t":"ad#qq.com", "id":"935de002-10e0-437f-a571-e74bb6646228" }, { "advertiser_email_t":"wang#qq.com", "id":"2a80935e-e520-4c3e-8d56-8e7b1096b372"}] } }
This is field definition:
<dynamicField name="*_t" type="text_general" indexed="true" stored="true"/>
This is field type definition:
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
After changed field name to "email":
{
"responseHeader": {
"status": 0,
"QTime": 0,
"params": {
"sort": "email asc",
"indent": "true",
"q": ":",
"_": "1383822359034",
"wt": "json"
}
},
"response": {
"numFound": 2,
"start": 0,
"docs": [
{
"email": "ad1#qq.com",
"id": "00000000-0000-0000-0000-000000000002"
},
{
"email": "ad#qq.com",
"id": "00000000-0000-0000-0000-000000000001"
}
]
}
}
You need to change your query to sort by the field named email instead of advertiser_email_t. Something like
q=*:*&sort=email+asc
As according to the response you posted, you try to sort by the field named advertiser_email_t. This field is of the type text_general you also provided. That field type is tokenized and receives additional tokens by the mapped synonyms.
When reading in the reference about sorting you can see that this cannot work
Solr can sort query responses according to document scores or the value of any indexed field with a single value (that is, any field whose attributes in schema.xml include multiValued="false" and indexed="true"), provided that:
the field is non-tokenized (that is, the field has no analyzer and its contents have been parsed into tokens, which would make the sorting inconsistent), or
the field uses an analyzer (such as the KeywordTokenizer) that produces only a single term.
But your field named email is fine. It is of type string, which is sortable.