Closed brototyp closed 6 years ago
@mplackowski If I get your issue correctly, that is exactly what the uid
is for. Is there a specific reason why you want to "synchronize" the cid instead of the uid?
So the problem with uid
is that it can only by used to track some percent of all visitors - they must be logged in.
Considering typical user flow there is no way to track them from the top of the funnel basing on the uid
, that is created somewhere in the middle (e.g landing page -> cart -> login -> checkout -> receipt).
I just realized that the _id
parameter can be used in the same way as cid
- not sure what is the difference between them. In general they both have impact on the log_visit.idvisitor column
in DB so I assume it is better to just use the _id
since it is already implemented in the SDK.
With this in mind, my idea is to allow overriding the _id
parameter. It could be done by making one more public variable in MatomoTracker following the visitorID/userID style: https://github.com/matomo-org/matomo-sdk-ios/blob/develop/MatomoTracker/MatomoTracker.swift#L22
This would probably look like this:
@objc public var clientId: String? {
get {
return matomoUserDefaults.clientId
}
set {
matomoUserDefaults.clientId = newValue
visitor = Visitor.current(in: matomoUserDefaults)
}
}
This way the tracker could by updated with new _id
paramter as soon as the pk_vid
is passed to the app via deeplink.
Also such approach allows adding the uid independently.
The final output is that all tracked actions/visits always have consistent records in the idvisitor
column and can be joined easily. At the same time, only some visits will provide additional info - if the userid column is non null. But frequently, especially during the first steps in the funnel, records in this column will be null
@mplackowski Sorry for not replying in quite a while.
There is one downside to this concept. An that is that you "lose your visitor" the moment when you actually set the clientId
. It is then counted as a completely new visitor.
I get your point that the user has to be logged, so that one can set the uid to the actual email of the user. One alternative would be to set some unique value to the uid if the user is not logged in. And once the user logs in either change it to the email or store this unique-value alongside with the e-mail so you then have a relation to the actual user.
What do you think about this alternative?
There is one downside to this concept. An that is that you "lose your visitor" the moment when you actually set the clientId. It is then counted as a completely new visitor.
So in my scenario I would like to set it in the app before the sdk sends the very first event from that app instance. By default for all organic installs it won't be used at all, but for installs from deeplinks (e.g branch.io links) when the vistor id is passed as a parameter I could store it in user defaults and use for every tracked event. So in current code the _id is autogenerated and then stored as long as the app is installed. My suggestion is to give option to provide such _id and if it is not provided then autogenerate.
I see your point. What do you think about my proposal / alternative by leveraging the clientId
?
One alternative would be to set some unique value to the uid if the user is not logged in. And once the user logs in either change it to the email or store this unique-value alongside with the e-mail so you then have a relation to the actual user.
Well in my opinion this approach makes a simple thing quite complicated. At first the vistor is tracked on the mobile website where no login option is available, so with this solution I would need to use the uid already on the mobile websites, then pass the uid to the mobile app and finally keep it somwhere along with the real uid once the user logs in. It is weird flow especially when I know that there is the separate "idvistor" column that stores info about all users on both action and visit levels.
Recently I realized that when Matomo detects uid in the request the _id is completely ignored and to the idvisitor column some hashed value from the uid will be inserted instead. I don't know the details why it works this way, but from my point of view the solution is only one - stop using the uid. Instead I will send user id as custom dimension in visit scope.
Such approach makes the idivistor column values consistent so the pk_vid passed from mobile website will be always respected by server side. Also at the same time I will keep record about logged in users though the reports must be done either by custom segments or by direct queries to DB.
So to sum up, firstly I think that the _id parameter should by customizable so the client sdk can track users from websites ( which is similar to cross domain visitor tracking) and secondly tracking logged in users is performed in a 'very specific' way by Matomo so to keep data clean I will keep uid's in separate dimension
Hi @mplackowski, thanks a million for your elaborate explanation. I am a little hesitant to let the user change the clientId because there is a little bigger chance of using it in a wrong way and thus losing information. I will check what the backend team thinks about this and will think about what is the best way to do this while reducing the risk of using it wrongly as much as possible.
I fully understand your point of view and the responsibility that is necessary here.
In the Android SDK it is possible to access the SharedPreferences and update them before initializing the tracker. I'm not sure it thats the best design but it worked in our usecase.
For my needs I just used the source code with few modifications.
What is the clientId in the iOS SDK?
When it comes to the SDK API here is my suggestion:
setVisitorId
. visitorId must be a 16 hexadecimal characters visitor ID, eg. "33c31e01394bdc63"._id
(current behavior)cid
parameter_id
(only for cid
)Hope this helps?
Hi @mattab, thanks a lot for your feedback!
Just a short recap of what SDK is currently doing and how things are named:
visitor.id
that is randomly generated on the first time any event is generated and then set as _id
on every event sent.visitor.userid
that is nil/not set per default and can be set by the user of the SDK. The value is then sent as uid
.If I understand you correctly I would change the following.
visitor.visitorid
which is nil per default and can be set to a 16 character hex string by the user of the SDK._id
will still always be set in the API.cid
will be set to the visitor.visitorid
value whenever this is set.uid
will be set to the visitor.userid
value whenever this is set.Thus there can be the case that all three identifiers, _id
, cid
and uid
are set. Is that correct? Please correct me if I am wrong.
Yes, looks correct :+1:
FYI: in the PHP SDK we called visitorid
the forcedVisitorId
to maybe make it a bit more clear.
Hi @mplackowski,
I just created the PR #271 implementing this feature. If you find some time to review it and check if this solves your issue, it would be really great!
This got merged and will be part of the next release
As @mplackowski asked in #258: