Skip to content

Commit cc6886f

Browse files
committed
Merge pull request #35 from amplitude/revert_cookie_to_localstorage
Revert cookie to localstorage
2 parents f750cc5 + 8ef0be7 commit cc6886f

File tree

5 files changed

+150
-6
lines changed

5 files changed

+150
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## Unreleased
22

3+
* Localstorage is not persisted across subdomains, reverting cookie data migration and adding a reverse migration path for users already on 2.6.0.
4+
35
## 2.6.0 (November 2, 2015)
46

57
* Migrate cookie data to local storage to address issue where having cookies disabled causes SDK to generate a new deviceId for returning users.

amplitude.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,11 @@ var LocalStorageKeys = {
148148
LAST_IDENTIFY_ID: 'amplitude_lastIdentifyId',
149149
LAST_SEQUENCE_NUMBER: 'amplitude_lastSequenceNumber',
150150
LAST_EVENT_TIME: 'amplitude_lastEventTime',
151-
SESSION_ID: 'amplitude_sessionId'
151+
SESSION_ID: 'amplitude_sessionId',
152+
153+
DEVICE_ID: 'amplitude_deviceId',
154+
USER_ID: 'amplitude_userId',
155+
OPT_OUT: 'amplitude_optOut'
152156
};
153157

154158
/*
@@ -216,6 +220,7 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config, callback) {
216220
});
217221
this.options.domain = Cookie.options().domain;
218222

223+
_migrateLocalStorageDataToCookie(this);
219224
_loadCookieData(this);
220225

221226
this.options.deviceId = (opt_config && opt_config.deviceId !== undefined &&
@@ -334,6 +339,39 @@ Amplitude.prototype._sendEventsIfReady = function(callback) {
334339
return false;
335340
};
336341

342+
var _migrateLocalStorageDataToCookie = function(scope) {
343+
var cookieData = Cookie.get(scope.options.cookieName);
344+
if (cookieData && cookieData.deviceId) {
345+
return; // migration not needed
346+
}
347+
348+
var cookieDeviceId = (cookieData && cookieData.deviceId) || null;
349+
var cookieUserId = (cookieData && cookieData.userId) || null;
350+
var cookieOptOut = (cookieData && cookieData.optOut !== null && cookieData.optOut !== undefined) ?
351+
cookieData.optOut : null;
352+
353+
var keySuffix = '_' + scope.options.apiKey.slice(0, 6);
354+
var localStorageDeviceId = localStorage.getItem(LocalStorageKeys.DEVICE_ID + keySuffix);
355+
if (localStorageDeviceId) {
356+
localStorage.removeItem(LocalStorageKeys.DEVICE_ID + keySuffix);
357+
}
358+
var localStorageUserId = localStorage.getItem(LocalStorageKeys.USER_ID + keySuffix);
359+
if (localStorageUserId) {
360+
localStorage.removeItem(LocalStorageKeys.USER_ID + keySuffix);
361+
}
362+
var localStorageOptOut = localStorage.getItem(LocalStorageKeys.OPT_OUT + keySuffix);
363+
if (localStorageOptOut !== null && localStorageOptOut !== undefined) {
364+
localStorage.removeItem(LocalStorageKeys.OPT_OUT + keySuffix);
365+
localStorageOptOut = String(localStorageOptOut) === 'true'; // convert to boolean
366+
}
367+
368+
Cookie.set(scope.options.cookieName, {
369+
deviceId: cookieDeviceId || localStorageDeviceId,
370+
userId: cookieUserId || localStorageUserId,
371+
optOut: (cookieOptOut !== undefined && cookieOptOut !== null) ? cookieOptOut : localStorageOptOut
372+
});
373+
};
374+
337375
var _loadCookieData = function(scope) {
338376
var cookieData = Cookie.get(scope.options.cookieName);
339377
if (cookieData) {
@@ -343,7 +381,7 @@ var _loadCookieData = function(scope) {
343381
if (cookieData.userId) {
344382
scope.options.userId = cookieData.userId;
345383
}
346-
if (cookieData.optOut !== undefined) {
384+
if (cookieData.optOut !== null && cookieData.optOut !== undefined) {
347385
scope.options.optOut = cookieData.optOut;
348386
}
349387
}

amplitude.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/amplitude.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ var LocalStorageKeys = {
4242
LAST_IDENTIFY_ID: 'amplitude_lastIdentifyId',
4343
LAST_SEQUENCE_NUMBER: 'amplitude_lastSequenceNumber',
4444
LAST_EVENT_TIME: 'amplitude_lastEventTime',
45-
SESSION_ID: 'amplitude_sessionId'
45+
SESSION_ID: 'amplitude_sessionId',
46+
47+
DEVICE_ID: 'amplitude_deviceId',
48+
USER_ID: 'amplitude_userId',
49+
OPT_OUT: 'amplitude_optOut'
4650
};
4751

4852
/*
@@ -110,6 +114,7 @@ Amplitude.prototype.init = function(apiKey, opt_userId, opt_config, callback) {
110114
});
111115
this.options.domain = Cookie.options().domain;
112116

117+
_migrateLocalStorageDataToCookie(this);
113118
_loadCookieData(this);
114119

115120
this.options.deviceId = (opt_config && opt_config.deviceId !== undefined &&
@@ -228,6 +233,39 @@ Amplitude.prototype._sendEventsIfReady = function(callback) {
228233
return false;
229234
};
230235

236+
var _migrateLocalStorageDataToCookie = function(scope) {
237+
var cookieData = Cookie.get(scope.options.cookieName);
238+
if (cookieData && cookieData.deviceId) {
239+
return; // migration not needed
240+
}
241+
242+
var cookieDeviceId = (cookieData && cookieData.deviceId) || null;
243+
var cookieUserId = (cookieData && cookieData.userId) || null;
244+
var cookieOptOut = (cookieData && cookieData.optOut !== null && cookieData.optOut !== undefined) ?
245+
cookieData.optOut : null;
246+
247+
var keySuffix = '_' + scope.options.apiKey.slice(0, 6);
248+
var localStorageDeviceId = localStorage.getItem(LocalStorageKeys.DEVICE_ID + keySuffix);
249+
if (localStorageDeviceId) {
250+
localStorage.removeItem(LocalStorageKeys.DEVICE_ID + keySuffix);
251+
}
252+
var localStorageUserId = localStorage.getItem(LocalStorageKeys.USER_ID + keySuffix);
253+
if (localStorageUserId) {
254+
localStorage.removeItem(LocalStorageKeys.USER_ID + keySuffix);
255+
}
256+
var localStorageOptOut = localStorage.getItem(LocalStorageKeys.OPT_OUT + keySuffix);
257+
if (localStorageOptOut !== null && localStorageOptOut !== undefined) {
258+
localStorage.removeItem(LocalStorageKeys.OPT_OUT + keySuffix);
259+
localStorageOptOut = String(localStorageOptOut) === 'true'; // convert to boolean
260+
}
261+
262+
Cookie.set(scope.options.cookieName, {
263+
deviceId: cookieDeviceId || localStorageDeviceId,
264+
userId: cookieUserId || localStorageUserId,
265+
optOut: (cookieOptOut !== undefined && cookieOptOut !== null) ? cookieOptOut : localStorageOptOut
266+
});
267+
};
268+
231269
var _loadCookieData = function(scope) {
232270
var cookieData = Cookie.get(scope.options.cookieName);
233271
if (cookieData) {
@@ -237,7 +275,7 @@ var _loadCookieData = function(scope) {
237275
if (cookieData.userId) {
238276
scope.options.userId = cookieData.userId;
239277
}
240-
if (cookieData.optOut !== undefined) {
278+
if (cookieData.optOut !== null && cookieData.optOut !== undefined) {
241279
scope.options.optOut = cookieData.optOut;
242280
}
243281
}

test/amplitude.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,72 @@ describe('Amplitude', function() {
7474
amplitude.init(apiKey, userId, null, callback);
7575
assert.equal(counter, 1);
7676
});
77+
78+
it ('should migrate deviceId, userId, optOut from localStorage to cookie', function() {
79+
var deviceId = 'test_device_id';
80+
var userId = 'test_user_id';
81+
82+
assert.isNull(cookie.get(amplitude.options.cookieName));
83+
localStorage.setItem('amplitude_deviceId' + '_' + apiKey, deviceId);
84+
localStorage.setItem('amplitude_userId' + '_' + apiKey, userId);
85+
localStorage.setItem('amplitude_optOut' + '_' + apiKey, true);
86+
87+
amplitude.init(apiKey);
88+
assert.equal(amplitude.options.deviceId, deviceId);
89+
assert.equal(amplitude.options.userId, userId);
90+
assert.isTrue(amplitude.options.optOut);
91+
92+
var cookieData = cookie.get(amplitude.options.cookieName);
93+
assert.equal(cookieData.deviceId, deviceId);
94+
assert.equal(cookieData.userId, userId);
95+
assert.isTrue(cookieData.optOut);
96+
97+
assert.isNull(localStorage.getItem('amplitude_deviceId' + '_' + apiKey));
98+
assert.isNull(localStorage.getItem('amplitude_userId' + '_' + apiKey));
99+
assert.isNull(localStorage.getItem('amplitude_optOut' + '_' + apiKey));
100+
});
101+
102+
it ('should migrate data from localStorage to cookie but preserve existing values', function() {
103+
var deviceId = 'test_device_id2';
104+
var userId = 'test_user_id2';
105+
106+
// use amplitude1 to set cookie values
107+
amplitude.init(apiKey, userId, {deviceId: deviceId});
108+
assert.equal(amplitude.options.deviceId, deviceId);
109+
assert.equal(amplitude.options.userId, userId);
110+
assert.isFalse(amplitude.options.optOut);
111+
112+
var cookieData = cookie.get(amplitude.options.cookieName);
113+
assert.equal(cookieData.deviceId, deviceId);
114+
assert.equal(cookieData.userId, userId);
115+
assert.isFalse(cookieData.optOut);
116+
117+
// remove deviceId to make amplitude2 go through migration process
118+
cookie.set(amplitude.options.cookieName, {
119+
'userId': userId,
120+
'optOut': false
121+
});
122+
123+
// set local storage values and verify that they are ignored by the init migration
124+
localStorage.setItem('amplitude_deviceId' + '_' + apiKey, deviceId);
125+
localStorage.setItem('amplitude_userId' + '_' + apiKey, 'test_bad_user_id'); // ignored
126+
localStorage.setItem('amplitude_optOut' + '_' + apiKey, true); // ignored
127+
128+
var amplitude2 = new Amplitude();
129+
amplitude2.init(apiKey);
130+
assert.equal(amplitude2.options.deviceId, deviceId);
131+
assert.equal(amplitude2.options.userId, userId);
132+
assert.isFalse(amplitude2.options.optOut);
133+
134+
cookieData = cookie.get(amplitude.options.cookieName);
135+
assert.equal(cookieData.deviceId, deviceId);
136+
assert.equal(cookieData.userId, userId);
137+
assert.isFalse(cookieData.optOut);
138+
139+
assert.isNull(localStorage.getItem('amplitude_deviceId' + '_' + apiKey));
140+
assert.isNull(localStorage.getItem('amplitude_userId' + '_' + apiKey));
141+
assert.isNull(localStorage.getItem('amplitude_optOut' + '_' + apiKey));
142+
});
77143
});
78144

79145
describe('runQueuedFunctions', function() {

0 commit comments

Comments
 (0)