Firefox - displaying web notifications from extension/addon - javascript

I'm building Firefox addon (with addon-SDK) and I'd like to display desktop notification to a user.
There is Notification object but it doesn't seem to work from addon code (background page). There is no error etc, but no dialog for permissions is displayed, so no notifications can be displayed. I've tried of course adding permissions/desktop-notifications but no effect.
Edit: pasting sample code I've tried (the code is located inside callback function for socket.io event. Event is received properly, but no notification is displayed, or request for permission.
Notification.requestPermission( function(status) {
console.log(status); // notifications will only be displayed if "granted"
var n = new Notification("title", {body: "notification body"}); // this also shows the notification
});
I've also found alerts service this one works. However alerts disappear quite fast (too fast for me) - edit: that's the way it works - so guess no code sample needed, as I don't see any option to make them last longer.
Is there any way to display chrome like notifications on Firefox? (chrome.notifications.create) Or at least use web notifications object from within the addon?

If you're using the add-on SDK, you're looking at the wrong docs. Here are the notification docs.
You create a notification like so:
var notifications = require("sdk/notifications");
notifications.notify({
title: "Jabberwocky",
text: "'Twas brillig, and the slithy toves",
data: "did gyre and gimble in the wabe",
onClick: function (data) {
console.log(data);
}
});
All the docs you look at should be a subset of developer.mozilla.org/en-US/Add-ons/SDK.

Related

Branch.io: javascript detect whether mobile app is installed

I have a web page where I want a particular link on a page to open our native mobile app if the app is installed, and if not, do what it is currently doing (which submits a form).
Note: I think this is different than a smart banner - I don't want the banner on this page. I just want the normal app flow if there is no mobile app.
I have integrated branch-sdk in the web page and in my ios app. I have successfully set up a deep link from the web page to the iOS app (code not shown), but I am not getting results I expect when sniffing for whether the app is installed.
Here's the code in the <head> of my webpage:
branch.init('MY_KEY', null, function(err, data) {
console.log('init...');
console.dir(data);
});
branch.setIdentity('test-user', function(err, data) {
console.log('identity...');
console.dir(data);
});
branch.data(function(err, data) {
console.log('data...');
console.dir(data);
})
Here's my code in application(_:didFinishLaunchingWithOptions:) in the iOS side:
//Initialize Branch
if let branch = Branch.getInstance() {
branch.setDebug()
branch.initSession(launchOptions: launchOptions, andRegisterDeepLinkHandler: { params, error in
if let params = params, error == nil {
// params are the deep linked params associated with the link that the user clicked -> was re-directed to this app
// params will be empty if no data found
// ... insert custom logic here ...
print("params: %#", params.description)
}
})
branch.setIdentity("test-user")
} else {
readerLog.error("failed to initialize branch")
}
Every time I load the webpage (even after loading it, and following the deep link), I get the following as output in the console. Note that +isfirstsession is true, and the hasApp property is null:
[Log] init... (localhost, line 18)
[Log] Object (localhost, line 20)
data: "{\"+is_first_session\":true,\"+clicked_branch_link\":false}"
data_parsed: {+is_first_session: true, +clicked_branch_link: false}
has_app: null
identity: null
referring_identity: null
referring_link: null
[Log] identity... (localhost, line 23)
[Log] Object (localhost, line 25)
identity_id: "352945822373397525"
link: "https://nlfd.app.link/?%24identity_id=352945822373397525"
link_click_id: "352947632809063724"
referring_data: "{\"$one_time_use\":false,\"+click_timestamp\":1485387510,\"_branch_match_id\":\"352945819276765390\",\"_t\":\"352945819276765390\",\"referrer\":\"link_clic…"
referring_data_parsed: Object
session_id: "352945822337503746"
[Log] data... (localhost, line 28)
[Log] Object (localhost, line 30)
data: "{\"+is_first_session\":true,\"+clicked_branch_link\":false}"
data_parsed: null
has_app: null
identity: null
referring_identity: null
referring_link: null
What am I doing wrong? I was hoping I could just look at the has_app property after init or after setting the identity. Is it incorrect to assume that has_app would return true in this case? Is there a more appropriate way to do what I want to do?
Alex from Branch.io here:
Unfortunately the has_app parameter is not especially reliable. It's good enough for switching a button between displaying an Open or an Install label, but ideally you don't want to use it for functional things. This is a limitation caused by iOS: Apple doesn't allow web pages to query for which apps are installed on a device (for obvious privacy reasons), so Branch has to rely on cookie matching. This means if we can't match the cookie, or haven't seen the user recently, or the user clears their device cache, or the user has uninstalled the app since the last time Branch saw them, the value of has_app will be incorrect.
HOWEVER, even though Apple doesn't allow web pages to query access this data, iOS itself can still act on it. Universal Links do exactly this — when the user opens a Universal Link (which includes Branch links, assuming you got all the configuration done), the app will open if it is installed. If it is not installed, the user will be sent to the URL of the link. You just need to put a Branch link behind that button.
Note however that this doesn't work for form submission buttons, so you would need to come up with some UX workaround for this. Or you might be able to find a way to submit the form after a delay if the app doesn't open, by using a Javascript timer.

Subsequent Chrome extension notifications onAlarm never displayed again if user doesn't interact with current one

I'm writing a Chrome extension that reminds the user of something every X minutes, using event pages, alarms, and the Chrome extensions notifications API.
The problem is that if the user lets the notification window disappear (it's on screen for only ~10 seconds), it will never be displayed again. This seems like a bug in Chrome, but wanted to check if maybe I'm missing something.
chrome.alarms.create('remindUser', {
delayInMinutes: 1,
periodInMinutes: 5
});
chrome.alarms.onAlarm.addListener(function (alarm) {
chrome.notifications.create(alarm.name, {
type: 'basic',
title: 'Reminder',
message: '...',
buttons: [
{ title: 'Act on it' },
{ title: 'Later' }
]
}, function callback(notificationId) {
// nothing necessary here, but required before Chrome 42
console.log(notificationId, 'notifications ARE called repeatedly, but the window is not displayed');
});
});
Nothing special in manifest.json:
"permissions": ["alarms", "notifications", "storage", "contextMenus"]
If I click on the x button to close the notification, it will be displayed next time. But if I'm away from the computer and don't do anything when the notification shows up, it will never be displayed again. The console shows the remindUser notifications ARE called repeatedly [...] message with an increasing count, but the notification is not displayed again.
How can this be fixed? I'd rather not use the Notification API because it bugs the user for permission.
The reason this happens is that the notifications always have the same ID, alarm.name. This causes subsequent notifications to replace previous ones as indicated at
https://developer.chrome.com/extensions/notifications#method-create
After removing the ID from the chrome.notifications.create call, all notifications are displayed. There is still the issue that they'll be hidden under Chrome's bell icon in the system tray though, while notifications generated with the Notification API never disappear:
Not sure what the reason is for the inconsistency between the two notification APIs in how persistence/docking into the system tray are handled, so I filed a bug with Chromium.

Meteor send to active users

I starting with writing a meteorjs webpage. I started with the leaderboard example. This works great. I added some new functions. I added a jquery notification script. (Noty http://ned.im/noty/ )
When I give a person five points a activate the Noty plugin by using this code
var n = noty({text: txt,timeout: 2000});
......
Template.leaderboard.events({
'click input.inc': function () {
Players.update(Session.get("selected_player"), {$inc: {score: 5}});
notje("Er heeft iemand een score gegeven");
Method.call("callHouse");
},
The notification will only displayed to my browser and not to other users. How can i use a notification to all active users.
Users -> Server -> All users
I hope you can help me with this issue
You would have to create a notifications collection (client & server):
notifications = new Meteor.Collection("notifications");
Then insert your message in there and display it using an observe handle. Make sure you add something which is user specific so that you can use a smaller subset of users. And also identify when its used and mark them as ready so they're no longer published and the user doesn't keep receiving them.
Then you could do something like this on your client side:
Meteor.startup(function() {
notifications.find().observe({
added: function(doc) {
//Message can be contained in doc.txt
//Not sure if this bit is right, but basically trigger the notification:
n = noty({text: doc.txt,timeout: 2000});
}
});
});
Hopefully this gives you a bit of a rough idea on how to do it.

Chromium error with SPDY when using Facebook JavaScript SDK

I develop a mobile application with HTML5 + Cordova (Phonegap) using Facebook Javascript SDK for iOs and Android.
I implement it like this :
FB.api(
{
method: 'fql.query',
query: 'SELECT uid, name, birthday_date FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me())'
},
function(response) {
console.log(response);
// some code
});
It worked for several months on Android & iOs, until yesterday, on Android.
An error occurs when the call to the api is doing and the callback function is not called.
Here is the error from LogCat in eclipse :
02-26 12:27:10.526: W/chromium(22379):
external/chromium/net/spdy/spdy_session.cc:1246:
[0226/122710:WARNING:spdy_session.cc(1246)] Could not parse Spdy
Control Frame Header. 02-26 12:27:10.526: D/chromium(22379): Unknown
chromium error: -337 02-26 12:27:10.526: W/chromium(22379):
external/chromium/net/spdy/spdy_session.cc:1058:
[0226/122710:WARNING:spdy_session.cc(1058)] Received data frame for
invalid stream 1 02-26 12:27:10.526: W/chromium(22379):
external/chromium/net/spdy/spdy_session.cc:1058:
[0226/122710:WARNING:spdy_session.cc(1058)] Received data frame for
invalid stream 1
It seems to be an error of the android browser Chromium when calling query Facebook (which using the protocol spdy)
Anyone has an idea ?
Thank you !
Seeing the same thing!
/chromium( 1942): external/chromium/net/spdy/spdy_session.cc:1246: [0307/015242:WARNING:spdy_session.cc(1246)] Could not parse Spdy Control Frame Header.
W/chromium( 1942): external/chromium/net/spdy/spdy_session.cc:1058: [0307/015242:WARNING:spdy_session.cc(1058)] Received data frame for invalid stream 21
W/chromium( 1942): external/chromium/net/spdy/spdy_session.cc:1058: [0307/015242:WARNING:spdy_session.cc(1058)] Received data frame for invalid stream 21
D/chromium( 1942): Unknown chromium error: -337
Found news about FB implementing SPDY without much news:
http://zoompf.com/2013/03/facebook-adds-spdy-support
Surprised we're not seeing more issues around.
I have the same problem with the similar code under identical
circumstances, PhoneGap, Android
The solution is to switch to Graph
API. Using Graphi API the same call will be
FB.api('/me/friends', { fields: 'id, name, gender, username' }, function (response) { ... });
There are a number of caveats that might
not be applicable to you but were applicable to me
The fields named differently. “sex” is now “gender”, for example Graph API does not
have direct analog of is_app_user field. If you add it to the list
of fields, you’ll get an error. There is a workaround asking
specifically for the users who installed the app
There is paging
implemented in response. So the response is structured a bit
differently. If you used to pass the data for processing to
functions you shall pass not “response” but “response.data”, and
watch for “response.paging”, to see if there are more friends to add
by additional calls.

Paypal Embedded Flow not using returnUrl or cancelUrl

I am using Paypals Adaptive Payments and Embedded flow feature to provide checkout via a minibrowser. Everything seems to be working correctly in the sandbox environment except that when the payment is completed successfully, the user is never redirected to my returnUrl set in the PAY API request. Same goes for my cancelUrl.
After the payment is complete, the user is shown an order overview in the minibrowser and a button labelled "close". If a user clicks this button, the minibrowser is closed.
If a user clicks cancel at any time, the minibrowser is closed.
There doesn't seem to be a way to have my page aware of the change besides setting up some polling or something which doesn't make sense, my returnUrl and cancelUrl should be used somewhere, right?
this is my code to get the redirect url (using adaptive payments gem):
pay_request = PaypalAdaptive::Request.new
data = {
'requestEnvelope' => {'errorLanguage' => 'en_US'},
'currencyCode' => 'USD',
'receiverList' =>
{ 'receiver' => [
{'email' => '...', 'amount'=> 10.00}
]},
'actionType' => 'PAY',
'returnUrl' => 'http://www.example.com/paid',
'cancelUrl' => 'http://www.example.com/cancelled',
'ipnNotificationUrl' => 'http://www.example.com/ipn'
}
pay_response = pay_request.pay(data)
redirect_to pay_response.approve_paypal_payment_url "mini"
And here is how I am setting up the paypal js:
var dg = new PAYPAL.apps.DGFlowMini({ trigger: "buyit", expType: "mini" });
It all seems pretty straight forward, not sure what I am missing.
Well - seems to be a bug on our side - just tried it myself and confirmed with our integration teams. :-(
Unfortunately the other short term fix I can think of other than what you've mentioned (checking for the existence of the popup window) is to call the PaymentDetails API from your server side to check the status of the Payment. I've opened the bug on our side but don't have an ETA.
Edit 10/18: Sorry I'm wrong. This is working - it's just that our developer guide is not providing all the required information. In case of the mini-browser flow, you would need to provide a 'callbackFunction' and also name your dgFlow variable as 'dgFlowMini'. (the latter is important - as apdg.js is expecting the 'dgFlowMini' variable to be defined) Here is the code that works:
var returnFromPayPal = function(){
alert("Returned from PayPal");
// Here you would need to pass on the payKey to your server side handle to call the PaymentDetails API to make sure Payment has been successful or not
// based on the payment status- redirect to your success or cancel/failed urls
}
var dgFlowMini = new PAYPAL.apps.DGFlowMini({trigger: 'em_authz_button', expType: 'mini', callbackFunction: 'returnFromPayPal'});
I have a working sample here: https://pp-ap-sample.appspot.com/adaptivesample?action=pay (make sure you select mini as the Experience Type)
We will get our docs updated and also cleanup apdg.js to remove the dependency on the JS variable name.
Looks like the PayPal experience for embedded flows has gotten worse. Now you'll receive an error message after invoking mini or lightbox that says "Payment can't be completed. This feature is currently unavailable."

Categories