How do I use trackPageView with Google Analytics (newest version)? - backbone.js

var url;
url = Backbone.history.getFragment();
return ga.push(['_trackPageview', "/" + url]); // is this right?
I get "undefined" does not have "push".
I am using the latest version of Google Analytics and Backbone.js.

Syntax for the current version (Universal Analytics) would be
ga('send', 'pageview', '/'+url);

Related

Not able to view cached static files in PWA

I have a React based PWA deployed on AWS Amplify and I'm trying to cache a few PDF documents for offline use. Using USB debugging I found that the documents are effectively added to the cache. However, when I try to open a document in offline mode, I'm presented with an blank page which seems to correspond to the bare index.html of my app. My documents are located in public/documents, and service-worker.js has this added at the end:
var CACHE_NAME = "app-documents";
var urlsToCache = [
"/documents/document_1.pdf",
"/documents/document_2.pdf",
"/documents/document_3.pdf"
];
self.addEventListener("install", event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function (cache) {
return cache.addAll(urlsToCache);
})
);
});
I'm linking from my app to the documents with a simple hyperlink:
<p>Document</p>

Login with Google using Ionic framework gives 404 on callback

I am trying to implement login with Google in an Ionic browser based app. These are the commands I ran to install and create my app:
ionic start tracker sidemenu
cd tracker
cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git
ionic platform add browser
When I click my login button, the Google auth comes up ok. However when the callback is called I get a 404:
Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8100/callback?code=xxxxxx
This OAuth 2 Ionic example gave this code:
var clientId = 'xxxxxx-3rpu226qm-xxxxx.apps.googleusercontent.com';
var scope = 'profile email';
var ref = window.open('https://accounts.google.com/o/oauth2/auth?client_id=' + clientId +
'&redirect_uri=http://localhost:8100/callback&scope=https://www.googleapis.com/auth/urlshortener&approval_prompt=force&response_type=code&access_type=offline',
'_blank', 'location=no');
ref.addEventListener('loadstart', function (event) {
console.log('listener event.url: ' + event.url);
if ((event.url).startsWith("http://localhost:8100/callback")) {
var requestToken = (event.url).split("code=")[1];
console.log('request token from google: ' + requestToken);
ref.close();
}
});
Why isn't the eventListener catching the callback?
Its a known issue of the cordova-plugin-inappbrowser that loadstart and loaderror events are not being fired in the browser.
Source: https://github.com/apache/cordova-plugin-inappbrowser#browser-quirks-1
You might want to look at an other javascript library like hello.js for the browser case (https://adodson.com/hello.js/#hellojs). Or implement it yourself. Here you can find an example for how to do it for google oath2 yourself: https://developers.google.com/identity/protocols/OAuth2UserAgent

Facebook login with Javascript SDK: Given URL is not allowed by the Application configuration

I got this error in the Chrome's console when using Javascript SDK to implement the Facebook login:
Given URL is not allowed by the Application configuration: One or more
of the given URLs is not allowed by the App's settings. It must match
the Website URL or Canvas URL, or the domain must be a subdomain of
one of the App's domains.
I tried to call the FB.getLoginStatus function and then the error happend. I already researched Question 1 and Questions 2 and followed instructions and still cannot resolve this error.
The url of the page which calling the function is: http://channels.daily.sg.tripolis.vn/channels#/new/add_channel_a (I'm using AngularJS)
This is my App's setting:
https://drive.google.com/file/d/0Bya9VnleW-F-TUhWRUZhX3Rxb2M/view?usp=sharing
and this is my AngularJS code to setup the SDK:
this.tokyo = angular.module('tokyo');
this.tokyo.run(['$rootScope', '$window',
function($rootScope, $window) {
$window.fbAsyncInit = function() {
// Executed when the SDK is loaded
FB.init({
appId: '570857916302626',
cookie: true, // enable cookies to allow the server to access
xfbml: true,
version: 'v2.4' // use version 2.2
});
};
// Load the SDK asynchronously
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
// Here we run a very simple test of the Graph API after login is
// successful. See statusChangeCallback() for when this call is made.
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
What did I do wrong ?
You might need to specify “Valid OAuth redirect URIs” on the Settings->Advanced tab in your app dashboard.
The “Given URL” the error message talks about is the one used as value for the redirect_uri parameter in the login dialog call. If you did not specify it yourself, then it was done by the SDK, automatically based on what page you are currently on.
I’d suggest you try a URL without the hash part for “Valid OAuth redirect URIs”.

Firebase Google Login

Firebase deprecated FirebaseSimpleLogin, so we've been trying to implement the new authWithOAuthPopup, but we keep getting a console error: TypeError: undefined is not a function.
var app = angular.module("myApp", ["firebase"]);
app.controller("appCtrl", function($scope, $firebase) {
var ref = new Firebase("https://[forge].firebaseio.com/users");
// Login using Google
$scope.loginGoogle = function() {
console.log("Got into google login");
ref.authWithOAuthPopup("google", function(error, authData) {
console.log("yeah, we got in! " + user.uid);
}, {
remember: "sessionOnly",
scope: "email"
});
};
$scope.logout = function() {
ref.unauth();
};
});
What am I doing wrong?
The delegated authentication methods (i.e. authenticating via OAuth providers, or email / password, etc.) were added to Firebase core client libraries on October 3rd 2014, and will require a client library from that date or later (>= 1.1.0 for the web client).
Grab the latest web client library, and view the changelog, at https://www.firebase.com/docs/web/changelog.html.
Be sure to use the latest version of Firebase, otherwise it will not understand the ref.authWithOAuthPopup method
Here is the latest version: https://cdn.firebase.com/js/client/2.0.2/firebase.js

AngularJS html5Mode fallback in IE. Express server needs to know route

I'm using html5Mode=true with AngularJS routing. Works fine. When I access the site with IE, Angular routing falls back to Hashbang URI's like http://example.com/#!/route-name. That's all fine. Except in Express I need to know the route, because it tells me which html file to serve from Express. The # part of the url is not sent to the server.
My question is, how can I let my server know which AngularJS route is being requested with hashbang routing in IE? I was thinking of configuring Angular somehow to send the route as an http header that I can read in express, but I don't know how to do that. Any ideas?
Update: Based on feedback I got, let me tell you that the site has templates. One for the homepage and one for all the other pages. They are both pretty different. Based on the route, the server needs to know when to serve the file for the homepage and when to serve the file for the other pages.
Just to be clear: this won't send the hashbang on the main page request. Based on the HTTP specifications there is no way of doing that.
You can send it on subsequent AJAX requests, but this won't really help you with solving this problem. There is no solution other than not supporting browsers that don't support html5mode.
Browsers won't send the hashbang to the server automatically, so yes you will need to send it manually. Using a header is a good option.
Take a look at $httpProvider.interceptors in the docs.
You can register a request interceptor for $http (AngularJS uses it internally for any AJAX request and so should you) that attaches a custom header. You can then set that header value to be the actual hashbang using $location.path():
var app = angular.module('MyApp',[]);
app.factory('httpInterceptor', function($q, $location) {
return {
'request': function(config) {
if(config.url.indexOf('product')) {
config.headers.Hashbang = $location.path();
}
return config;
}
};
});
app.config(function($httpProvider) {
$httpProvider.interceptors.push('httpInterceptor');
});
app.controller('Ctrl', function($scope, $http) {
$http({method: 'GET', url: '/echo/json/'}).
success(function(data, status, headers, config) {
console.log(data);
});
});
Here's the fiddle. You can test it like so. Check out the sent headers in developer tools.
Notice that I'm not testing with a true hashbang (#!) but just a hash because the fiddle does not allow it.
I had a similar problem where I needed the parameters of the URL before they were removed by the redirect. As the URL is redirected in angular from the original one the previous URL is in the referer header.
So I used this express 3.x middleware to rewrite the original parameters from the referer to the query on requests to the root URL:
var _ = require('lodash');
var url = require('url');
var qs = require('querystring');
app.use(function(req, res, next) {
if (req.url === '/' && req.headers && req.headers.referer) {
var referer = url.parse(req.headers.referer);
// rewrite original parameters
_.forEach(qs.parse(referer.query), function(value, key) {
req.query[key] = value;
});
// do something with pathname
console.log(referer.pathname);
}
});
You could do the same in your case for the path, that is in referer.pathname.
There seems no client-side answer as per the answer of Sergiu Paraschiv. So I have investigated a server-side solution that requires only one thing on the client. Make sure you always links as you would do in html5Mode which is linking to /xxxxx and not /#!/xxxxx.
Then In html5Mode and IE9 and lower what happens is that AngularJS redirects everything /xxxxx to /#!/xxxxx. In Express this makes the url / and the referer /xxxxx. This is something that you can check for quite easily.
If you want to cater for IE8 and lower to, it's unfortunate that Angular uses window.location.href in this fall back scenario redirecting to /#!/xxxxx. See github / angular.js / src / ng / browser.js line 169.
Using window.location.href causes IE8 and lower to not send the referer.
Here's a server-side (Express 3.x) solution that resolves the Angular hashbang route from the referer value or a previousUrl session variable for IE8 and lower.
app.use(function(req, res, next) {
if (req.url.match(/\/api/))
return next(); // /api/something should proceed to next in middleware
console.log(req.url, req.headers)
//IE does not support html5Mode so /xxxxx is redirected to /#!/xxxxx
//effectively making the url / and the referer /xxxxx
//I check for that here and if xxxxx is not home I present page.html
if (req.headers['user-agent'] &&
req.headers['user-agent'].match(/MSIE ([7-8]{1}[.0-9]*)/) &&
req.url.match(/^\/[\w-]+$/)
) {
//However IE8 does not report the referer when doing a redirect using window.locarion.href
//so I store the initially requested url /xxxxx in session...
req.session.previousUrl = req.url;
//console.log('IE8 saving the url here', req.session.previousUrl);
}
if (req.headers['user-agent'] &&
req.headers['user-agent'].match(/MSIE ([7-8]{1}[.0-9]*)/) &&
!req.headers['referer'] &&
req.url === '/' &&
req.session.previousUrl &&
req.session.previousUrl !== '/home'
) {
//continuation on the IE* referer story (aka the next redirected request)...
//... and checked for the url stored in session here ;)
return res.sendfile('public\\page.html');
}
if (req.headers['user-agent'] &&
req.headers['user-agent'].match(/MSIE ([7-9]{1}[.0-9]*)/) &&
req.url === '/' &&
req.headers['referer'] &&
req.headers['referer'].match(/^https?:\/\/(?:www)?\.example\.com\/(?!home$)([\w-]+)$/)
) {
return res.sendfile('public\\page.html');
}
if (req.url.match(/\/home|\/$/))
return res.sendfile('public\\home.html'); //for the home pages we're going to use home.html
res.sendfile('public\\page.html'); //for everything else we're going to use page.html
});
I'm sure that there are scenario's where this fails, but it worked for me in my tests and if it fails, that will only fail for IE9- browsers (as per the regexp's).

Resources