Reputation: 29714
I'm hoping I've not gotten the wrong end of the stick here (as always the sitecore documentation is woeful!)
I wanted a way to store information against a visitor, I'm reasonably new to sitecore, but the contact facets seemed the idealsolution, pretty much implemented word for word from the link above, until it hit production I was quite pleased with it. When I stored information it persisted, I could read it:
public IMpmVisitorFacet GetMpmVisitorFacet()
{
return _contact.GetFacet<IMpmVisitorFacet>(_MPMVisitorConfigName);
}
and set info and everything seemed great. I could also see the sitecore SC_ANALYTICS_GLOBAL_COOKIE
being set, everything seemed wonderful. Then I did some more thorough tests...
The problem appears to be that the data just doesn't persist for long. If I put some info into the facet it will hang around for an hour or so (I can close my browser, look at other, sites, etc. etc.) and I'll be able to access it but after an "amount of time" it just all goes away.
Having revisited the docs (have I mentioned that they're not very good) I noticed a caveat in a sentence that I didn't see before:
Well, I can create another web form page that only reads the employee number. That will show me that the contact facet data is being stored in memory at least. But what about permanent storage?
Hold on, I thought this was permanent storage?! So the example shows some code to read the "facet".
var contact = Tracker.Current.Contact;
var data = contact.GetFacet<IEmployeeData>("Employee Data");
data.EmployeeId = "ABC123";
.....
<p>Employee data contact facet updated.</p>
<p>Contact ID: <b><%=contact.ContactId.ToString()%></b></p>
<p>Employee #: <b><%=data.EmployeeId%></b></p>
But this facet seems to only exist for a short period of time. It then goes on:
For performance reasons Sitecore only writes contact data to xDB when the session ends.This means that if I look in MongoDB...
it then goes on to show the data in it's new shiny trendy mongoDb implementation. But what use is it in mongo if I can't actually access and use that information programatically!
So this raises the question how do I access this contact information once the session is abandoned?
i.e. user logs into my site -> I add some information into their contact facet -> they come back the next day -> I want to read the information I added previously
There are several other docs which talk about accessing this data in the experience profile, to index into Lucene and in the Experience platform(why have two products with almost the exactly same name?!) but nothing to say how to access this information in the web site itself, in code.
To add to the comments by Dmytro Shevchenko:
So it appears to be an issue with writing the new information to mongo...Does anyone have any help or similar experience of this?
Upvotes: 4
Views: 1237
Reputation: 182
Your problem lays in regards how you pulling the contact: If you are in a page request, you should access the current contact via Tracker.Current.Contact. your code is not in a page request, but the user may have a live session, use the ContactManager with the methods described above. If the contact is not in a live session right now, you should use ContactRepository. See an example on how to use it here. Copied from https://sitecore.stackexchange.com/questions/3319/why-are-custom-xdb-facets-being-overwritten-on-session-end answered by Dmitry Shevchenko.
Upvotes: -1
Reputation: 29714
After a great deal of debugging, fiddling and testing I finally figured this out. My issue, it turned out, wasn't the writing to mongo it was in the reading back out of mongo once it had been written.
The sitecore documentation seems (as usual) to completely miss a rather fundamental part of the working of this. About a third of the way down the docs it states:
public EmployeeData() { base.EnsureAttribute<string>(FIELD_EMPLOYEE_ID); }
The "EnsureAttribute" method is the equivalent of declaring a value-type variable.
Ok, this is very misleading. What this EnsureAttribute
appears to do is load the data for the facet into the current class from mongo. If you don't do this for every property in your facet then it does not set the value from the mongoDb! This was my mistake, I hadn't "ensured" every property in the class.
So what was happening is,
SC_ANALYTICS_GLOBAL_COOKIE
does this for you)So the EnsureAttribute
does not "declare a value type" (this is just totally wrong in my opinion) it loads the data out of mongodb and into the current Session
.
Upvotes: 2
Reputation: 3216
I think the step you might be missing here is the Tracker.Current.Session.Identify()
method to identify a known contact. The data in the Tracker api only lasts for the current session and you need to load the contact into the session.
The implementation of xDB relies on a contact identifying themselves when they visit the site, by logging in or registering for example.
Once they have logged in you can use a unique identifier e.g email address and pass this to the identify method -Tracker.Current.Session.Identify("Email Address of the visitor")
.
Once you have called this method, if the user has identified themselves previously, the contact data will be loaded into the current session and any existing facet information will be available in the Tracker Api.
Upvotes: 0