I am working on an ionic2 project and trying to show connection status message in the app. Here is my code:
import { ToastController, Toast } from 'ionic-angular';
connectedToast: Toast; disconnectedToast: Toast;
this.connectedToast = this.toast.create({
message: `You are now ${networkstatus.connectType} via ${networkstatus.networkType}`,
position: 'bottom',
cssClass: 'toast-connected',
duration: 3000
});
this.disconnectedToast = this.toast.create({
message: `This function is not available because you are ${networkstatus.connectType}`,
position: 'bottom',
cssClass: 'toast-disconnected'
});
if(networkstatus.isOnline) {
if(this.disconnectedToast != null)
this.disconnectedToast.dismiss();
this.connectedToast.present();
}
if(networkstatus.isOffline) this.disconnectedToast.present();
What I wanted to achieve is: if offline, toast msg will stay there until it is online. But for online message, it will only display for 3 seconds. Everything is working fine except when it is online and after online message is displayed, the offline toast msg stays there and didn't disappear even though I called dismiss(). Did I miss anything here?
my environment is: "ionic-angular": "3.3.0", "ionic": "3.6.0",
"typescript": "2.3.3"
Any help will be appreciated!
Related
I am trying to take pictures from an Ionic 4 PWA application.
I read this docs from Ionic team and implemented all the proposed steps... (https://capacitor.ionicframework.com/docs/guides/ionic-framework-app/)
The (weird) result can be seen in the picture below:
When the camera prompt seen in this picture is shown, Chrome console prints out an object called MediaStreamTrack with this values:
kind: "video"
id: "6250dfa4-d9aa-4a87-ab9f-ae085f929c3f"
label: "screen-capture-recorder"
enabled: true
muted: false
onmute: null
onunmute: null
readyState: "live"
onended: null
contentHint: ""
proto: MediaStreamTrack
When I click in the button to take picture, I can see this message:
Unable to take photo! DOMException: setOptions failed - pwa-camera.entry.js:259
I have used the sample code the Ionic team presented in the docs:
export class Tab2Page {
photo: SafeResourceUrl;
constructor(
private sanitizer: DomSanitizer
) { }
async takePicture() {
const image = await Plugins.Camera.getPhoto({
quality: 100,
allowEditing: false,
resultType: CameraResultType.DataUrl,
source: CameraSource.Camera
});
this.photo = this.sanitizer.bypassSecurityTrustResourceUrl(image && (image.dataUrl));
}
}
And...
<ion-content>
<img [src]="photo">
<ion-fab vertical="bottom" horizontal="center" slot="fixed">
<ion-fab-button (click)="takePicture()">
<ion-icon name="camera"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
I changed everything in this code trying to figure out what is going wrong, but nothing seem to fix this behavyour.
Can anyone point me in the right direction?
My Chrome version is 79.0.3945.79
Thanks in advance.
My app is under ionic 4 angular.
I've installed the pwa part with :
ng add #angular/pwa --project app
Then I build with : ionic build --prod
and deployed to firebase with : firebase deploy
But I have 2 problems :
1) the banner "add to screen" is not shown when I browse the app from my android phone.
Even with this code on the root url :
showBtn: boolean = false;
deferredPrompt;
constructor(private modalController: ModalController, public authUser: AuthUserService, private router: Router){}
ionViewWillEnter(){
window.addEventListener('beforeinstallprompt', (e) => {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later on the button event.
this.deferredPrompt = e;
// Update UI by showing a button to notify the user they can add to home screen
this.showBtn = true;
});
//button click event to show the promt
window.addEventListener('appinstalled', (event) => {
alert('installed');
});
if (window.matchMedia('(display-mode: standalone)').matches) {
alert('display-mode is standalone');
}
}
2) When I launch lighthouse audit I get this warning :
Does not register a service worker that controls page and start_url
I've tried to uninstall, reinstall, rebuild everything but nothing works.
On ionic docs I can't find any clue to fix this problem.
After many days I was able to make it works.
First I add this following snippet to the firebase.json file to the hosting property:
{
"source": "ngsw-worker.js",
"headers": [
{
"key": "Cache-Control",
"value": "no-cache"
}
]
}
Then I add this script in my index.html :
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('ngsw-worker.js')
.then(() => console.log('service worker installed'))
.catch(err => console.error('Error', err));
}
</script>
Now it works !
Hello I'm trying to install a custom PWA "Add to Homescreen".
The ServiceWorkerRegistration is successful.
But the function beforeinstallpromp is not calling after register.
<script type="text/javascript">
function request_debug(paramdata){
document.getElementById('output').innerHTML += '<BR>'+ paramdata;
}
window.addEventListener('load', function() {
document.getElementById('output').style.display = "block";
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js').then(function(registration) {
console.log('Service worker registrado com sucesso:', registration);
request_debug(registration);
}).catch(function(error) {
console.log('Falha ao Registrar o Service Worker:', error);
request_debug(error);
});
var isTooSoon = true;
window.addEventListener('beforeinstallprompt', function(e) {
//e.preventDefault();
//e.prompt();
//promptEvent = e;
request_debug(' window.addEventListener beforeinstallprompt fired!')
if (isTooSoon) {
//e.preventDefault(); // Prevents prompt display
// Prompt later instead:
setTimeout(function() {
isTooSoon = false;
e.prompt(); // Throws if called more than once or default not prevented
}, 4000);
}
});
}else{
console.log('serviceWorker not in navigator');
request_debug('serviceWorker not in navigator');
}
});
</script>
Also my service worker in root directory...
HTTPS is secure!
my manifest:
{
"background_color": "purple",
"description": "lojaportaldotricot TESTE",
"display": "standalone",
"icons": [
{
"src": "/componentes/serviceWorker/fox-icon.png",
"sizes": "192x192",
"type": "image/png"
}
],
"name": "lojaportaldotricot",
"short_name": "lojaportaldotricot",
"start_url": "/dashboard"
}
It's only workes when I set "Enable" chrome://flags/#bypass-app-banner-engagement-checks
Edit: Look's like I've found the problem. The Audits tabs of Chrome's DevTools(F12) gives debugging information.
Try this :
<script>
let deferredPrompt;
window.addEventListener('beforeinstallprompt', function(event) {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
});
// Installation must be done by a user gesture! Here, the button click
btnAdd.addEventListener('click', (e) => {
// hide our user interface that shows our A2HS button
btnAdd.style.display = 'none';
// Show the prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
deferredPrompt = null;
});
});
</script>
beforeinstallprompt will only be fired when some conditions are true :
The PWA must not already be installed
Meets a user engagement heuristic (previously, the user had to interact with the domain for at least 30 seconds, this is not a requirement anymore).
Your web app must include a web app manifest.
Your web app must be served over a secure HTTPS connection.
Has registered a service worker with a fetch event handler.
Along with all of those steps above, also check that the app is uninstalled here:
chrome://apps
Just deleting the app from the Chrome Apps folder on your Mac does not seem to remove it from Chrome
If the app was previously installed, the beforeinstallprompt will not be triggered, and no errors will be thrown either :(
Yes, the "start_url" is incorrect in the manifest.
IF ANY PART OF THE MANIFEST IS BROKEN 'beforeinstallprompt' is not fired.
The event is not fired because... the manifest start_url is incorrect.
My favorite way to figure this out is to look in the > NETWORK tab of DevTools for 404's.
AND the other way to see why manifest is broken is to run > AUDIT in DevTools and see what the error is. Like what #sealabr found:
"Failures: Service worker does not successfully serve the manifest's start_url, Timed out waiting for fetched start_url.' Which means the 'start_url"
This thread was a big help troubleshooting production. Thanks.
Are you including the manifest file in the page header?
<link rel="manifest" href="/manifest.json">
To whoever needs to read this: A little side-note that I ran into when working on my Vue3 app while trying to figure out the prompt:
The beforeInstallPrompt will trigger shortly after the page load.
So make sure you set up the event listener close to the page load. Took me a couple of hours to find this out. I was trying to add the event listener somewhere down the line of onboarding the user. Way after the page load. And couldn't figure out why the prompt didn't show.
here is another reason why beforeinstallprompt is not triggered on a mobile device (observed on an Android device with Chrome):
A symbol file defined in manifest.webmanifest could not be found on the web server (the mobile browser reported a 404). That was the reason why beforeinstallprompt was not triggered in my case.
#example
// your manifest
{
/* ... */
"icons": [
{
"src": "maskable_icon_x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
/*...*/
]
}
Make sure that all icon files (such as maskable_icon_x192.png) are present on your web server.
All the best,
Tom
I have this code in my application:
$ionicPopup.alert({
title: $scope.header1,
template: 'The was a problem connecting to the server. Please check your internet connection and try again.'
});
ionic.Platform.exitApp()
what I have noticed is that in Android, the application exits quickly without showing the pop up message. What I wanted to do is execute
ionic.Platform.exitApp()
after the user press the 'Ok' button in the pop-up. ls there something like an "onleave" event in ionic Popup?
The best approach may be to define your own 'OK' button as opposed to leveraging the default dismiss one - that way you can invoke ionic.Platform.exitApp() upon the user clicking/tapping your button.
Example:
import { AlertController } from 'ionic-angular';
constructor(private alertCtrl: AlertController) {
}
presentAlert() {
let alert = this.alertCtrl.create({
title: YourCustomHeader,
//subTitle: 'optional text',
message: 'The was a problem connecting to the server. Please check your internet connection and try again.',
buttons: [
{
text: 'OK',
handler: () => {
ionic.Platform.exitApp();
}
}
]
});
alert.present();
}
Reference: https://ionicframework.com/docs/api/components/alert/AlertController/#usage
I've added ionic cloud services to my app and want to use the native FaceBook authentication.
import { FacebookAuth } from '#ionic/cloud-angular';
this.facebookAuth.login()
When running this function on an Android phone, as expected I get the Facebook prompt to ask if my app can get permissions to read profile and email. When I click YES, the function returns an empty ERROR object:
Object {}
I'm sure I am catching it right, because when I choose CANCEL on the FB prompt, I get this error object:
Object {errorCode: "4201", errorMessage: "User cancelled dialog"}
Note: I'm using remote web inspector in chrome to see the full console. Unfortunately, as this requires a real device I can not Plunker this. However, I hope someone has an idea why this could happen. I have followed all these steps, including the FB developer settings, the hash and the ionic.io settings.
I have done that and it's working fine on the real device.If you have any question, please comment below.
Play with Git Repo
app.module.ts
import { CloudSettings, CloudModule } from '#ionic/cloud-angular';
const cloudSettings: CloudSettings = {
'core': {
'app_id': 'd32c02d2'
},
'auth': {
'facebook': {
'scope': ['public_profile', 'email']
}
}
};
#NgModule({
declarations: [
],
imports: [
CloudModule.forRoot(cloudSettings)
],
bootstrap: [IonicApp],
entryComponents: [
],
providers: [
]
})
export class AppModule { }
home.html
<button ion-button block type="button" (click)="fbLogin()">Fb Login</button>
home.ts
import { Component } from '#angular/core';
import { FacebookAuth, User } from '#ionic/cloud-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public facebookAuth: FacebookAuth, public user: User) {
}
fbLogin() {
this.facebookAuth.login();
}
}
Ok it's quite silly, but the first root cause was that the FB user I was trying to log in with was not registered as a tester. Apparently in that case, an empty error is returned by the plugin.
After adding as a tester, I received a real error (Andoird manifest dod not allow internet access). After fixing that issue, again I'm getting an empty error.
So my assumption is that some of the errors returned by FB are not well communicated by the plugin and so any other FB error can be causing this issue.
UPDATE 23/04: There seems to be a change from FB side, now the FB login screen did not succeed but gave an error about the hashing key. After fixing that issue, the FB login is working now.