I am using OneSignal in my Laravel/Vue app. I have included it within <head> as stated in documentation:
<script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script>
<script>
var OneSignal = window.OneSignal || [];
OneSignal.push(function() {
OneSignal.init({
appId: "{{ env('ONESIGNAL_APP_ID') }}"
});
OneSignal.showNativePrompt();
});
</script>
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/OneSignalSDKWorker.js')
.then(function () {
console.log('Service worker registered');
})
.catch(function (error) {
console.log('Service worker registration failed:', error);
});
} else {
console.log('Service workers are not supported.');
}
</script>
I also have a service worker of my own, so I've followed the documentation here as well.
What is happening after a hard reset is that service worker gets installed and it is all fine, however once I refresh the page I am getting:
OneSignalPageSDKES6.js?v=151102:1 Uncaught (in promise) InvalidStateError: The current environment does not support this operation.
at Function.getServiceWorkerHref (https://cdn.onesignal.com/sdks/OneSignalPageSDKES6.js?v=151102:1:41510)
at xe. (https://cdn.onesignal.com/sdks/OneSignalPageSDKES6.js?v=151102:1:144028)
at Generator.next ()
at r (https://cdn.onesignal.com/sdks/OneSignalPageSDKES6.js?v=151102:1:716)
And I have no idea what does that mean? What is "current environment"? Where to start debugging? I've tried putting console logs around it, however it led me nowhere...
You would start debugging by looking at the source code of the library.
In your case your library is the OneSignal SDK for browsers.
Let's do this!!!
We can see that this error is thrown by getServiceWorkerHref function (which is defined here) and the error message is driven by the InvalidStateReason enumeration:
case InvalidStateReason.UnsupportedEnvironment:
super(`The current environment does not support this operation.`);
break;
If you look at the first linked file, you will see the note on getServiceWorkerHref OneSignal developers left for the those who dare venture into their source code:
else if (workerState === ServiceWorkerActiveState.Bypassed) {
/*
if the page is hard refreshed bypassing the cache, no service worker
will control the page.
It doesn't matter if we try to reinstall an existing worker; still no
service worker will control the page after installation.
*/
throw new InvalidStateError(InvalidStateReason.UnsupportedEnvironment);
}
As you can see, the error is raised when the service worker has the "Bypassed" state. What is that, you may ask? Let's look at ServiceWorkerActiveState enumeration below, in the same file:
/**
* A service worker is active but not controlling the page. This can occur if
* the page is hard-refreshed bypassing the cache, which also bypasses service
* workers.
*/
Bypassed = 'Bypassed',
It seems, when the browser "hard-refreshes" the page, it bypasses the service worker and OneSignal can't properly initialize when that happens. Hard-refresh can happen for a number of reasons — here are some of them (to the best of my knowledge):
if you click the refresh button a bunch of times (usually seconds consecutive refresh within a short period of time may trigger this)
if you have caching disabled in your DevTools
if the server sets a no-cache header
What is happening after a hard reset
I don't know exactly what you mean by "hard reset", but that sounds like it would trigger this issue. I would suggest you close your browser and then visit the page you are working on without using "reset" functions — theoretically, the service worker should be used for caching on consecutive visits and that would ensure OneSignal can function.
Related
I am using Firebase in my app and I've noticed when I am actively making changes and LiveSync updates the app it will sometimes say "firebase.init error: Firebase already initialized". This happens when the changes don't trigger a whole application restart (ex. an html file). It completely messes up my current authentication state and forces me to restart the app anyways.
Is there some way I can catch for this happening or prevent it? I can try to make a demo app for it, but I feel this might have happened to somebody already.
I am just using the standard firebase.init as shown in the documentation in my app.component, nothing special or different.
Instead of using on ngOnit of App.component, try to initlize firebase on app launch event.
applicationOn(launchEvent, (args: LaunchEventData) => {
firebase.init({
// Optionally pass in properties for database, authentication and cloud messaging,
// see their respective docs.
}).then(
function () {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
});
I'm trying to build an app that does something when it is first installed onto a workspace, eg: Ping every team member.
I couldn't find an event type that gets triggered upon app install:
https://api.slack.com/events
Is there a way to make this happen?
I think there might be a misunderstanding of the events concepts here. Events are always directly linked to one specific Slack app and needs to be processed by that very app. There is no such thing as "general" events for things happening on a workplace, like a new app being installed. Ergo there is no event for app installation.
Nevertheless you can implement the functionality you mentioned with Slack, e.g. pinging all team members once an app is first installed. All you need to do is include this function in the installation process of your Slack app and e.g. start pinging after the installation process is complete and the app verified that it was the first installation to this workspace. You do not need an event for that.
This is a partial answer because I was wondering the same thing and wanted to share what I found. On this oauth tutorial, it has the following code snippet:
app.get('/auth', function(req, res){
if (!req.query.code) { // access denied
return;
}
var data = {form: {
client_id: process.env.SLACK_CLIENT_ID,
client_secret: process.env.SLACK_CLIENT_SECRET,
code: req.query.code
}};
request.post('https://slack.com/api/oauth.access', data, function (error, response, body) {
if (!error && response.statusCode == 200) {
// Get an auth token
let oauthToken = JSON.parse(body).access_token;
// OAuth done- redirect the user to wherever
res.redirect(__dirname + "/public/success.html");
}
})
});
I believe instead of the line res.redirect(__dirname + "/public/success.html"); at that point you can make a request to ping everyone or even call a function to do so directly there, and it will trigger immediately once the app has been installed.
I am new to service worker and workbox. I am currently using the workbox to precache my static assets files, which works fine and I expect my other thirdparty URL to be cached too during runtime, but not working until my second reload on the page:(
Shown Below is the copy of the Code of my Service Worker, please note that I replace my original link to abc.domain.com intentionally :)
workbox.routing.registerRoute(
//get resources from any abc.domain.com/
new RegExp('^https://abc.(?:domain).com/(.*)'),
/*
*respond with a cached response if available, falling back to the network request if it’s not cached.
*The network request is then used to update the cache.
*/
workbox.strategies.staleWhileRevalidate({
cacheName: 'Bill Resources',
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
);
workbox.routing.registerRoute(
new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'),
//serve from network first, if not availabe then cache
workbox.strategies.networkFirst(),
);
workbox.routing.registerRoute(
new RegExp('^https://use.(?:fontawesome).com/(.*)'),
//serve from network first, if not availabe then cache
workbox.strategies.networkFirst(),
);
I have cleared storage times without number, I refreshed cache storage from google developer tools, but all seems to be the same. Resources from a custom link, google fonts and fontawesome, fail to be cached the first time. Below is the console and the Cache Storage Tab for my page first load image and the second load Image respectively.
Please I dont know what I am doing wrong and why it behaves like so.
Thanks in Advance
This is expected behaviour.
The way service workers get set up is that they will have an install and activate phase, where installation can happen when ever a new service worker is registered or a service worker updates.
A service worker will then activate when it's safe to do so (i.e. no windows are currently being "controlled" be a service worker).
Once a service worker is activated, it'll control any new pages.
What you are seeing is:
Page is loaded and the page registers a service worker
The service worker precaches any files during it's install phase
A service activates but isn't controlling any pages
You refresh the page and at this point the page is controlled and requests will go through the service worker (resulting in the caching on the second load).
The service worker will not cache anything until its been activated. It gets activated only on the second hit itself. To achieve caching on the first hit you have to guide service worker to skip waiting for activation. you can do this by
self.addEventListener('install', () => {
self.skipWaiting(); //tells service worker to skip installing and activate it
/*your code for pre-caching*/
});
once its been skipped it enter the activated mode and will wait for caching but it wont cache the clients interaction. To do so apply the following line
self.addEventListener('activate', () => {
clients.claim();
});
which starts caching on the first hit itself
I'm using SignalR 2 and I'm having problems when I open multiple tabs of the same page. After opening 4 or 5 tabs, all the requests get in pending status, like if I had exceeded the maximum allowed by the browser. If I close a few tabs, everything works again. Even with all the tabs opened, if I open a different browser it works. This happens both in Chrome and Firefox. If I disable SignalR, I can open as many tabs as I want.
This is my code:
// Reference the auto-generated proxy for the hub.
notificator.hub = $.connection.messageHub;
// Create a function that the hub can call back to display messages.
notificator.hub.client.refreshNotifications = function () {
// business code
};
$.connection.hub.start().done(function () {
notificator.hubStarted = true;
});
$.connection.hub.disconnected(function () {
notificator.hubStarted = false;
setTimeout(function () {
$.connection.hub.start();
}, 2000); // Restart connection after 2 seconds.
});
If I remove the handler for disconnected event, the problem persists. The notification system works correctly so SignalR is doing its job but it's causing me issues in the app. It's even slower.
I found two solutions:
1) In my case, it's an intranet web application so I know that everybody supports WebSockets and WebSockets doesn't have the connection limitation. But, why this was not working? well, first I added logging to SignalR by adding this line:
$.connection.hub.logging = true;
Then I tried to force using WebSockets:
$.connection.hub.start({ transport: 'webSockets' }).done(function () { .. });
But, checking the logs I found out that WebSockets were not supported because they were not installed in the server. So, I followed these steps in Windows 2012 and installed it:
Open Server Manager.
Under the Manage menu, click Add Roles and Features.
Select Role-based or Feature-based Installation, and then click
Next.
Select the appropriate server, (your local server is selected by
default), and then click Next.
Expand Web Server (IIS) in the Roles tree, then expand Web Server,
and then expand Application Development.
Select WebSocket Protocol, and then click Next.
Click Install.
Source: http://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-websocket-protocol-support
After that, everything worked. In Chrome, under Network tab, you'll find a WS filter. Click on it and you should see the websocket.
2) Using IWC-SignalR:
https://github.com/slimjack/IWC-SignalR
It works this way:
One of the windows becomes a connection owner (choosen randomly) and
holds the real SignalR connection. If connection owner is closed or
crashed another window becomes a connection owner - this happens
automatically. Inter-window communication is done by means of IWC.
I have problems with facebook application based on flash which communicate with PHP using FBJS-bridge. When someone use the application for the first time, he/she is asked for various permissions. After that, flash contact PHP with ajax but request is never sent. When you refresh page, everything is working without any problems.
If you remove the application on privacy settings, refresh the page and try again - same bug happens. If you allow application, refresh page, in other tab remove application and start application in previous tab - user is asked for permissions but everything is working after allowing application.
This is FBJS code
function openPermissions(){
Facebook.showPermissionDialog(/*permissions string*/, permissionOnDone);
}
function permissionOnDone(perms){
if (!perms) {
document.getElementById("indexswf").callSWF('noallow');
} else {
document.getElementById("indexswf").callSWF('allow');
}
}
function ajaxCall(url,parameters){
var params = {};
for(var i=0;i<parameters.length;i+=2){
params[parameters[i]]=parameters[i+1];
}
ajax = new Ajax();
ajax.requireLogin = true;
ajax.responseType = Ajax.RAW;
ajax.ondone = function(data){
document.getElementById("indexswf").callSWF('parseAjax', data);
}
ajax.post('http://the.url.to/the_real_server/not_to_the_fb_url/'+url,params);
}
openPermissions is called to display permission dialog, and on allow flash function allow() is called. In flash, allow() calls JS function ajaxCall(), which should make ajax request. But, ajax.post never sends request. I know that for sure, because flash function parseAjax was never called and also debugging tools in browsers are not showing any ajax requests. URL and parameters are same as when it is working. No flash or JS errors are detected...
Anyone have idea what is wrong here? Maybe facebook bug again since this was all working few days ago...
ajax.requireLogin = true should be set to false for some reason