Piwik, about custom variable in Visitor Log - matomo

I've installed Piwik and was trying out the custom variable features to track individual users of my website when I noticed something in the Visitor Log.
For example..when I logged in as "User1" , Visitor Log is able to capture this user's activities and set the custom variable as Visitor:User1, however when I switch to another username e.g "User2" using the same browser, somehow only the custom variable is replaced (in this case, User1 is replaced by User2). That is, there is no longer Visitor:User1, Visitor Log only shows Visitor:User2 and all the previous activities of User1 is now belong to User2.
So it looks like Visitor log will overwrite the custom variable whenever the IP(or when you are using the same browser? I'm not sure.) is the same, am I doing anything wrong? Or is this how it supposed to work?
Below is the code that I currently use to set my custom variable.
<script type="text/javascript">
var _paq = _paq || [];
_paq.push(['setCustomVariable',
1,
"Visitor",
"<?php
if(isset($_SESSION['user'])){ // this is where I track my users
echo $_SESSION['user'];
}?>",
"visit"
]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u=(("https:" == document.location.protocol) ? "https" : "http") + "MySiteAdress";
_paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['setSiteId', 1]);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.type='text/javascript';
g.defer=true; g.async=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
})();
Could anyone clarify this? Thanks in advance for your help!

The custom variable is set in a cookie that your are overwriting. If you clear cache/cookie you will see no issue.

_paq.push(['setCustomVariable',
1,
"Visitor",
"<?php
if(isset($_SESSION['user'])){ // this is where I track my users
echo $_SESSION['user'];
}?>",
"visit"
]);
You have set the 4th paramater (scope) to "visit". Maybe you want to try "page" instead and see if that's a good tracking plan for you?

Those guys obviously didn't read the question ^^
Yes, when you are tracking things and logged in as User X then log in as User Y on the same machine with the same browser, Piwik will update the records attributed to User X to be User Y... Since Piwik doesn't know you are logging in as different users, only that you are the same person on the same machine.

Related

firebase database child reference issue

I am trying to create a meeting firebase reference inside my parent users
I am implementing this line:
var meetingRef= firebase.database().ref('users/' + $rootScope.currentUser.$id + '/meetings');
Under my users, I have registered user Id's as hashes, which I make use of in the above code. As the current user gets authenticated, he gets to create some meetings from the UI. I want these meetings to go into his particular hash in the firebase database.
But every time I create a meeting, some undefined child reference of users gets created under which I see the meetings of authenticated users.
This is my complete code-
myApp.controller("MeetingsController",
['$scope','$rootScope','$firebaseArray',
function($scope,$rootScope,$firebaseArray){
var ref = firebase.database().ref();
var auth = firebase.auth();
auth.onAuthStateChanged(function(user) {
if (user) {
var meetingRef= firebase.database().ref('users/' + $rootScope.currentUser.$id + '/meetings');
var meetingsInfo=$firebaseArray(data);
$scope.addmeeting=function(){
meetingsInfo.$add({
name:$scope.meetingname,
date:firebase.database.ServerValue.TIMESTAMP
}).then(function(){
$scope.meetingname=' ';
})
};
}
});
}]);
If you are wondering as to where that $rootScope.users.$id value is coming. It comes from a service that I created and the $id is the value that the current authenticated user's hash is.
I want the meetings to go inside authenticated users hash. I think I am creating wrong reference path. How can I achieve this one?
Images attached:
Current:
Required:
Aakash,
Your code to create the meetings folder and the drawing you added to the post do not go together. Currently, you are using this:
var data = firebase.database().ref('users/' + $rootScope.currentUser.$id + '/meetings');
But if you really want meetings to be a direct child of users the way you have drawn then you will need to get rid of the user id piece of the reference like this:
var data = firebase.database().ref('users/meetings');
This is based off what you added to your post, however, something tells me that you didn't mean to draw meetings in there as a direct child to users. If that's what you really wanted, then that would be your answer.
This next piece is a guess, but is the following structure what you are trying to create?
Because if it is, you need something different which I can also help with, just let me know.
Update:
Ok, based on your comment, I see that you are going for the data structure in my picture.
It looks like your code is ok, however, at the exact moment that the data variable is being set, your $rootScope.currentUser.$id is undefined. This is possibly due to the asynchronous nature of javascript. This means that sometimes your user variable is true, however, your $rootScope.currentUser.$id is still not quite caught up and is undefined.
I would run a check on the variable before continuing, just to make sure everything is in order:
if($rootScope.currentUser.$id != undefined){
var data = firebase.database().ref('users/' + $rootScope.currentUser.$id + '/meetings');
}else{
return;
}
This will stop you from ever getting a new undefined object in your database.
I have found an answer to this one.
I changed the meetingRef to:
var meetingRef = firebase.database().ref('users/' + user.uid + '/meetings');
and it worked for me.

Linking Data in Firebase

I am designing a forum and have a layout like this in on my Firebase:
root
|-posts
|-postID1
|-creator: "userOne"
|-creatorUID: "simplelogin:1"
|-text: "Some Text"
|-postID2
|-creator: "userTwo"
|-creatorUID: "simplelogin:2"
|-text: "Some Other Text"
|-profile
|-simplelogin:1
|-firstName: "John"
|-user: "userOne"
|-simplelogin:2
|-firstName: "Sue"
|-user: "userTwo"
On my forum page. I simply use a Angular ng-repeat to get all of the posts on Firebase and list them out. I also want to print out the first name of whoever created the post, but right now, I can only access {{ post.creator }}, which just gives the username of the person who posted. How can I link the post's creator (or creatorUID) with the first name field of that person's profile?
If you're just displaying the the users firstName I would place the users name in the postIDX object.
This would be quicker and produce less requests to Firebase with you going back and fourth with each post to get the usersFirst name.
more information on structuring data and best practices can be found here: https://www.firebase.com/docs/web/guide/structuring-data.html
Updated from response
if you wanted to get the user details then within every request to the postIDx you'd need to do something similar to this (not tested and quick mock up).
var fbRef = new Firebase('firebase path'),
postDetailsObject = {};
fbRef.child('posts').once('value', function(snapshot) {
// loop through each post
snapshot.forEach(function(childSnapshot){
var postDetails = childSnapshot.val(),
profileDetails;
postDetailsObject.post = postDetails;
fbRef.child('profile/' + postDetails.creatorUID).once('value', function(profileData) {
postDetailsObject.profile = profileData;
});
})
});
Then return the postDetailsObject in to angular so you can loop through the single object.

Making a logged in user-variable in AngularJS+laravel

I'm trying to make a global variable called theUser which contains the userinfo if logged in.
I have tried putting this in my SPA php file:
app.value('theUser', '<?php echo Auth::user(); ?>');
And it works but only after refreshing page. (Login happens via angularjs logic + a $http request to auth/login which returns userinfo if logged in)
In my angular auth app, I have done this:
var login = $http.post("auth/login", sanitizeCredentials(credentials)).success(function(data) {
theUser = data;
$rootScope.theUser = theUser;
});
And that works, but only when the user logs in. If I refresh, theUser is empty. And I can't get these two solutions to work together. I probably need another approach.
All I want is an user variable that I can access from anywhere in my app,
which is set if the user logs in, or have been logged in before. Using Laravel 5.1.
Here is my auth app service js: http://pastebin.com/HcdLaZcD
How can I make this work?
Why dont you use PHP-Vars-To-Js-Transformer by Laracasts. Then whenever a User logs in, you could set a Session variable auth_user and then get that variable to JavaScript as shown below (in your Laravel AuthController#login):
...
\Session::put('auth_user', \Auth::user());
JavaScript::put([
'theUser' => \Session::get('auth_user')
]);
...
And when the User logs out: \Session::forget('auth_user');
theUser variable will be available anywhere in your JavaScript (or you can Namespace it also, check the Github link above).
on top of the page under script tag
window.user = <?php echo Auth::user(); ?>
and
app.value('theUser',window.user);
app.run(function ($rootScope, theUser) {
$rootScope.theUser = theUser;
});
For accessing the logged in user from your JavaScript files, you may try something like this (Create a view composer, also layouts.master dictates layouts/master.blade.php):
View::composer('layouts.master', function($view) {
$user = null;
if(Auth::check()) {
$user = Auth::user();
}
$view->with('authUser', $user);
});
In the master layout try this (So User variable will be available as JS object if the user is logged in):
<head>
<script>var User = {{ $authUser or 'undefined' }}</script>
</head>
This is just an idea, implement it according to your need. Also, you may use a namespace like App.user. I wrote an article about this lasr year, you may
check it here. Btw, it was for Laravel 4.x.
.
We have made use of html5 local storage to overcome this once the user is logged in, you just put the user's info on html5's local storage (works on all browsers, even mobile).
It has some drawbacks which you have to overcome, and also have some control on your routes filters to avoid someone loading page they shouldn't be allowed to see.
But I'm afraid my answer applies better to our solution and I don't think this answer is perfect but might guide you in a better solution. Our app publishes an API for angular's use and this angular is somewhat empowered with some extensions to ease routing.

passing user to the browser in meanjs

I'm reading source code of meanjs project to learn javascript and MEAN better. There is an expression:
<!--Embedding The User Object-->
<script type="text/javascript">
var user = {{ user | json | safe }};
</script>
I understand that it is sending the user record as a json object to the browser, but can't find 'safe' filter on google. Could anyone please point me to the right direction or explain what this is?
Yes, the user object is actually getting passed to the browser, and it actually displays in the source code. In practice, my deployed app has this in the source code (actual data generalized):
<!--Embedding The User Object-->
<script type="text/javascript">
var user = {"_id":"123abc456xyzetc","displayName":"First Last","provider":"local","username":"newguy","__v":0,"roles":["admin"],"email":"my#email.com","lastName":"Last","firstName":"First"};
</script>
As you can see, it actually dumps user information into the source code, which isn't the most secure way to develop an app. If you comment out or remove the line in your layout.server.view.html file (var user = {{ user | json | safe }};), then you can't really log in. It logs you in, then immediately kicks you out.
You'll notice, though, in your config > passport.js file that some information is removed before being passed back to the browser, starting at around line 14:
// Deserialize sessions
passport.deserializeUser(function(id, done) {
User.findOne({
_id: id
// The following line is removing sensitive data. In theory, you could remove other data using this same line.
}, '-salt -password -updated -created', function(err, user) {
done(err, user);
});
});
If you do decide to remove additional fields, though, be aware that this can break your app. I removed the user id, for example, and most of my app worked, but it broke some specific functions (I believe it was Articles, if I remember right).

Google Analytics don't seem to be firing

I've tried to look around many threads here around GA, I feel like I've done what's required. My site consist of HTML5 and angular.js, the page is structured roughly as follow (through ng-include)
index.html
|-header
--|-navigation
|-content
|-footer
when a link from navigation bar is clicked, the content will change (partials page in angular), header, footer stays the same.
The last script tag in my < head > is as follow (inside index.html)
<script type="text/javascript">
var globalLanguage = 'en';
// GA tracking variable
var _gaq = [['_setAccount', 'UA-XXXXXXXX-X'], ['_trackPageview']];
</script>
and at the bottom part of index.html, before the closing < / body > tag:
<script type="text/javascript">
(function(d, t) {
var g = d.createElement(t), s = d.getElementsByTagName(t)[0];
g.async = 1;
g.src = '//www.google-analytics.com/ga.js';
g.type = 'text/javascript';
s.parentNode.insertBefore(g, s);
}(document, 'script'));
</script>
All my angular controller function, call a common function as described in Tracking Google Analytics Page Views with Angular.js
function gaqPageView($scope, $location, $window) {
console.log('triggering google analytics');
$scope.$on('$viewContentLoaded', function(event) {
console.log('event triggered, tracking: ' + $location.path());
$window._gaq.push([ '_trackPageview', $location.path() ]);
});
}
I do see the console log statements, there's no error in the console either.
When I print out the content of _gaq, I do get an array that grows as I navigate around the page (which mean my _gaq.push call is working just fine).
However, in my the network call (in chrome dev tool), I don't see any _utm.gif call to Google Analytics. (Basics of Debugging Google Analytics Code: GA Chrome Debugger and other tools).
What am I missing here? seems like the google analytics is not firing off the event and reporting it?
Edit: I am pretty sure I am silly here, the _gaq variable itself is just a normal javascript array, so of course _gaq.push work just fine. But what am I missing to get Google Analytics to kick in and start sending the content of that _gaq?
Are you currently running your server on localhost, or an intranet name without a "." -- the tracking GIF request doesn't get made for localhost servers by default.
See Google Analytics GIF request not sent.
Another idea: Usually _gaq is defined as an array only if it's not already defined. If ga.js has already executed, you might be overwriting the _gaq object. It doesn't seem likely from your code organization, but...
Try replacing
var _gaq = [['_setAccount', 'UA-XXXXXXXX-X'], ['_trackPageview']];
with
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXXXX-X'], ['_trackPageview']);

Resources