Google analytics dimenson values are random guids - google-analytics

I am setting a custom dimension in GA with right index
window.ga('set', dimension5, value);
The value I am setting is true, false & error.
But when looking at the Google analytics dashboard I am getting some other values as well which are random guids, like:
(19dc2e4a-50cb-42ad-bb37-aa3129a72bcf,636229408930000000)
I am not setting those values but how am I getting those?
Here is the code snippet.
Hi Tony, thank you for getting back. I have done GA dimensions in past and have never experienced this problem. Dimension5 is a brand new dimension we have created and it has never been used in past.
My code looks like this.
variantAssignment.getVariant(contextId, success, failure);
function success(){
if(response.data.variantName === 'WithTrue')
sendGaEvent("true");
}else{
sendGaEvent("false");
}
}
function error(){
sendGaEvent("error");
}
function sendGaEvent(value) {
googleAnalyticsService.setDimension("dimension5", value);
}
The code in GoogleAnalyticsService looks like this.
function setDimension(dimension, value) {
if (window.ga !== undefined) {
window.ga('set', dimension, value);
}
}
And in the dashboard, my report looks like this.
**EnquiryReassuranceMVT** **Users**
false 20,181
true 1,307
058332c5-67e2-48b8-96e5-a7bf08aff7cc,636168368830000000 1
0f6fa9a1-ab32-497e-b817-02dbf4c70e26,636232937030000000 1
23dc5dec-aa78-4d4c-a53f-eaf4240b1123,636225308770000000 1
32f7ca5d-9158-4aec-8a9e-ca94f62bbc2c,636226820520000000 1
488866af-4301-4bb6-b055-804bbc3b6c83,636233922490000000 1
6140a30f-0aa0-4d85-992d-255006fc5a8b,636233678080000000 1

It is really difficult to answer you question without knowing your level of knowledge and experience with GA.
If you are not very experienced with it you may need to confirm report dates. Sometimes old values may be present in custom dimension, so you may see them.
If it is not the case, it will be helpful to see screenshots of all settings/code pieces and reports you are looking at, as with the information you provided helping you is more of a guessing game.

Related

Ordering data does not actually order anything

I'm trying to get a dataset of messages out of my firebase database and want the messages sorted by added/timestamp. But for some reason no orderby I put in the code is actually used. I tried doing these 2 things.
_messagesRef = FirebaseDatabase.instance.reference().child('messages/'+key);
_membersSubscription = _messagesRef
.orderByChild('timestamp')
.onValue//On valuechange
.listen((Event event) => _messagesSubscriptionCallback(event));
_messagesRef = FirebaseDatabase.instance.reference().child('messages/'+key);
_membersSubscription = _messagesRef
.orderByKey()
.onValue//On valuechange
.listen((Event event) => _messagesSubscriptionCallback(event));
Both give me back the same dataset that is not ordered by timestamp or key in the callback. I've added the output underneath
{
-LA-Aw6crEAV53LxdujP:{
sender:1508,
message:test s9 2,
timestamp:1523642778089
},
-LA-Arby61T1UG5URMn6:{
sender:1508,
message:test s9,
timestamp:1523642759679
},
-LA-AyC7F8KAqceZBE3j:{
sender:1509,
message:test emu 1,
timestamp:1523642786632
},
-LA22WiUfL2tbh7-OjtM:{
sender:1508,
message:Blaj,
timestamp:1523690904480
},
-LA-B29RRXbdOPT1mG7m:{
sender:1508,
message:tesy3,
timestamp:1523642806940
}
}
This is how the data should be.
I hope someone can help me with this issue. I think I might misunderstand how ordering data works with Firebase
Kind regards,
Namanix
The result you show is a JSON object with other objects in there. JSON objects are never ordered as far as I know, only retrievable by key. JSON Arrays would be, but it doesn't look like you get that. When you would change this to an array the document IDs would have to be inside the document instead of being the object key. My guess would be that 'orderBy' is meant to be used for example to limit the number of items you get for pagination. Than you can order by timestamp, limit the number of items to 20 and search from the last timestamp you got.
I think if you want to order them I would put them in a new list of objects which can be ordered.
Most likely (it's hard to be sure without seeing _messagesSubscriptionCallback) you're throwing the ordering information away when you convert the data from Firebase into a plain JSON object, which (as Rene also says) doesn't have any defined order.
But the data your request from Firebase does have ordering information, you just have to be sure to not drop it.
The usual way to do this is to listen for onChildAdded instead of onValue. With that Firebase will invoke onChildAdded for each child in turn, and it will do so in the order you requested.
Also see this example and for example what FirebaseAnimatedList does here.
I now temporarily fixed it by doing this in my callback. But this feels like a very bad way to fix it. I hope to get some thoughts on this.
static void _messagesSubscriptionCallback(Event event) {
_messagesList.clear();
_messages.clear();
_messages = event.snapshot.value;
_messagesList = _messages.keys.toList();
_messagesList.sort((a, b) {
return b.compareTo(a) ;
});
onMessagesChange();
}

.numChildren() always returning 0

I was following the likes example
using their exact structure, but for a different purpose:
/functions-project-12345
/db
/1
contacts_count: 0
/contacts
1: true
2: true
3: true
contacts_count gets created at the correct location, Although for some reason, contacts_count keeps returning 0
exports.contactsCount = functions.database.ref('/db/{userid}/contacts').onWrite(event => {
return event.data.ref.parent.child('contacts_count').set(event.data.numChildren());
});
I have also tried setting the trigger at /db/{userid}/contacts/{id}, and after reading all the docs, still I can't seem to get it to return the correct count.
in fact, having the exact same structure as in the likes example:
/functions-project-12345
/posts
/key-123456
likes_count: 32
/likes
user123456: true
user456789: true
user786245: true
and running on the server:
exports.countlikes = functions.database.ref('/posts/{postid}/likes').onWrite(event => {
return event.data.ref.parent.child('likes_count').set(event.data.numChildren());
});
still saves 0 into likes_count
is event.data in event.data.numChildren() a reference to the /db/{userid}/contacts node, right ?
UPDATE 04/13/17: The solution below only works if you can guarantee children nodes are only added (not deleted or changed) and does not handle the count node being deleted. For a more robust solution, check out the updated child count example in the firebase/functions-samples repo.
I'm not sure exactly what is going wrong with your code (I just tested the example and it works for me), but a safer way to do this same thing is to use transaction() instead of set(). Modifying your provided sample code, that would look like this:
exports. contactsCount = functions.database.ref('/db/{userid}/contacts')
.onWrite(event => {
var contactCountRef = event.data.ref.parent.child('contacts_count');
return contactCountRef.transaction(function(currentCount) {
return (currentCount || 0) + 1;
});
});
This code should work for you since it doesn't rely on whatever issue you are running into with numChildren() and it has the added benefit of being safe from race conditions that are present in the official sample. We are actually working to get the sample updated to properly use a transaction instead.

Meteor Dashboard and publication/subscription

EDIT: as the original question was too vague I have updated it to make it more concrete
I'd like to create a dashboard in Meteor that shows some statistics about my collections (e.g. how many docs, how many users...). I have been trying the past days but can't seem to find a good/intelligent way.
I initially just did the following:
Template.dashboard.helpers({
getProductsCount: function() {
return Products.find().count();
}
});
This did not work. I think because it counts the number of products from minimongo, but not sure.
Then I did the following:
In the template helper, call a method and get the value to show on the dashboard page (does not work)
Was told not to use pub/sub mechanism for this type of metric
Worked via Session variables (did work, but feels a bit strange to store this kind of metric data in Session variables
So then I read in another SO response about Reactive Variables and tried the following:
Template.dashboard.helpers({
getProductsCount: function() {
return Template.instance().myAsyncValue.get();
}
});
Template.dashboard.created = function() {
var self = this;
self.myAsyncValue = new ReactiveVar("Waiting for response from server");
Meteor.call('getProductsCount', function(error, asyncValue){
if (error)
console.log(error);
else
self.myAsyncValue.set(asyncValue);
});
};
This works, but I find this extremely difficult for something as simple as showing a product count (or any other metric). Not sure I understand the reason why I should use sth as reactive variables?
Then -out of curiosity- I tried the following (using meteor add simple:reactive-method) and it works:
Template.customerDashboard.helpers({
getProductsCount: function () {
return ReactiveMethod.call("getProductsCount");
}
});
So the question really is why having to use Reactive variables and methods for sth as simple as this. Can someone explain?
If you want to show the count only in the view, the best way is to return the count number only. you do not need publish/subscribe at all. you can use server methods. and if you want to show data also, you can go for pub-sub. and your approach is correct.

Firebase remove+limited query caching bug?

If I read a value from Firebase and then remove it, a subsequent limited read (e.g. dataRef.limit(10).once("value") ) will still see the removed value.
If I do an unlimited read, then I won't see the removed value, and a subsequent limited read will also no longer see the removed value.
var gFirebase = new Firebase("https://brianshmrian.firebaseio.com/");
function CreateValue()
{
gFirebase.child("TestBug/Key").set("Value");
}
function ReadValue(limit)
{
var dataRef = gFirebase.child("TestBug");
if (limit)
dataRef = dataRef.limit(10);
dataRef.once("value",function(snapshot)
{
alert((limit?"Limited read\n":"Normal read\n") + snapshot.val());
});
}
function RemoveValue()
{
gFirebase.child("TestBug/Key").remove();
}
In this example code, if I do a CreateValue(), then a ReadValue(), then a RemoveValue(), then a ReadValue(true), the object will still be reported to me in the last ReadValue(). However, if I do a ReadValue(false), I'll no longer see the value, and a subsequent ReadValue(true) will not see the value either.
See here to try it for yourself: http://jsfiddle.net/brianshmrian/5WWR6/
So is this a bug? Or am I making a mistake?
EDIT
Ok, that seems like a not too painful workaround. The code below solves my problem for now:
// Need to do this before the remove to avoid caching problem
dataRef.on("value", function(snapshot)
{
setTimeout(function() { dataRef.off(); }, 3000);
});
dataRef.remove();
I can't find any issues with the code. There is always the gotcha that locally cached data is returned synchronously, but I don't see that as an issue here; there's no way for the read to be getting called before the remove has completed. It looks like a pretty straightforward bug.
I was able to circumvent the behavior by setting up the limit(10).on('value') before calling the add/delete operations. So I think that if you establish your query ref first, you'll be okay.
Example: http://jsfiddle.net/katowulf/6wQFF/2/ (the pre tag is set up on load)

How can I achieve this search condition?

I want to implement some search condition like the below which I want to make in best optimized way, how can I achieve this?
switch (e.CommandName)
{
case "DRESS":
chkItem.Items.Clear();
chkItem.DataSource = cDressing.GetAllDressingDetail(cWebUtil.CurrClientID);
chkItem.DataTextField = "Description";
chkItem.DataValueField = "DressingID";
chkItem.DataBind();
CurrBtnMode = btnMode.Dressing;
// ModalPopupExtender1.TargetControlID = ((Button)grdOrder.Rows[currItem.OrderItemID -1].FindControl("btnDress")).ID.ToString();
if (currItem.DressingItems.Count > 0)
{
foreach(cOrderItemDressing itemDress in currItem.DressingItems )
{
// I want here to apply condtion for those chkItem object's DressingID exist in the itemDress objets's DressingID should
// have checked state in checkbox list to be populated.
}
}
ModalPopupExtender1.Show();
Is you goal to check the items in the chkItem.Items that have a matching item in the currItem.DressingItems collection? I'm not sure if this is what you want to get, but you can try this:
...
//uncheck all the items first (if you need it)
foreach (var item in chkItem.Items)
{
item.Checked = false;
}
foreach(cOrderItemDressing itemDress in currItem.DressingItems )
{
bool chkItemFound = false;
foreach (var item in chkItem.Items)
{
//if the item is found, make it checked
if (item.DressingID == itemDress.DressingID)
{
item.Checked = true;
chkItemFound = true;
break;
}
}
}
I haven't tested this yet, so if you've got some issues when using it, just let me know.
Update
You asked if it's the most optimized way of solving the issue. I would say there are more optimized methods, but I wanted to keep the code simple to just show the solution.
It may be sufficient, but it depends on how many items does each of the collections contain.
I suppose that a quite simple way to optimize it would be preventing so many items comparisons by removing an item you've already found (because it's not needed in further comparisons). This way the collection can shrink with each loop iteration, making it work faster. You may need, however, to create a copy of the collection you want to modify in order to have acces to its original form (and keep note that allocation of this array can take some time).
Another way would be using sorted collections and implementing some kind of searching algorithm for them. This will make the searching process itself faster, but needs some additional time to sort the collections (sorting can also be implemented by creating collection in a sorted form, so no sorting is needed later).
There are probably some other ways to do it, but it can depend on the details of other parts of your application and amount of data you want it to work with.

Resources