Skip to content

Commit 765ab7c

Browse files
committed
Restore legacy 2.0 code paths. This should fix issues where some props were not initialized correctly and some events were not sent
1 parent a2ed8ab commit 765ab7c

File tree

2 files changed

+76
-7
lines changed

2 files changed

+76
-7
lines changed

src/amplitude-client.js

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,13 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
9898
});
9999
this.options.domain = this.cookieStorage.options().domain;
100100

101+
if (this._instanceName === Constants.DEFAULT_INSTANCE) {
102+
_upgradeCookieData(this);
103+
}
101104
_loadCookieData(this);
102105
this._pendingReadStorage = true;
103106

107+
104108
const initFromStorage = () => {
105109
// load deviceId and userId from input, or try to fetch existing value from cookie
106110
this.options.deviceId = (type(opt_config) === 'object' && type(opt_config.deviceId) === 'string' &&
@@ -189,6 +193,7 @@ AmplitudeClient.prototype.init = function init(apiKey, opt_userId, opt_config, o
189193
});
190194
} else {
191195
initFromStorage();
196+
this.runQueuedFunctions();
192197
}
193198

194199
} catch (e) {
@@ -258,13 +263,15 @@ var _parseConfig = function _parseConfig(options, config) {
258263
* @private
259264
*/
260265
AmplitudeClient.prototype.runQueuedFunctions = function () {
261-
for (var i = 0; i < this._q.length; i++) {
262-
var fn = this[this._q[i][0]];
266+
const queue = this._q;
267+
this._q = [];
268+
269+
for (var i = 0; i < queue.length; i++) {
270+
var fn = this[queue[i][0]];
263271
if (type(fn) === 'function') {
264-
fn.apply(this, this._q[i].slice(1));
272+
fn.apply(this, queue[i].slice(1));
265273
}
266274
}
267-
this._q = []; // clear function queue after running
268275
};
269276

270277
/**
@@ -430,6 +437,60 @@ AmplitudeClient.prototype._setInStorage = function _setInStorage(storage, key, v
430437
storage.setItem(key + this._storageSuffix, value);
431438
};
432439

440+
var _upgradeCookieData = function _upgradeCookieData(scope) {
441+
// skip if already migrated to 4.10+
442+
var cookieData = scope.cookieStorage.get(scope.options.cookieName + scope._storageSuffix);
443+
if (type(cookieData) === 'object') {
444+
return;
445+
}
446+
// skip if already migrated to 2.70+
447+
cookieData = scope.cookieStorage.get(scope.options.cookieName + scope._legacyStorageSuffix);
448+
if (type(cookieData) === 'object' && cookieData.deviceId && cookieData.sessionId && cookieData.lastEventTime) {
449+
return;
450+
}
451+
452+
var _getAndRemoveFromLocalStorage = function _getAndRemoveFromLocalStorage(key) {
453+
var value = localStorage.getItem(key);
454+
localStorage.removeItem(key);
455+
return value;
456+
};
457+
458+
// in v2.6.0, deviceId, userId, optOut was migrated to localStorage with keys + first 6 char of apiKey
459+
var apiKeySuffix = (type(scope.options.apiKey) === 'string' && ('_' + scope.options.apiKey.slice(0, 6))) || '';
460+
var localStorageDeviceId = _getAndRemoveFromLocalStorage(Constants.DEVICE_ID + apiKeySuffix);
461+
var localStorageUserId = _getAndRemoveFromLocalStorage(Constants.USER_ID + apiKeySuffix);
462+
var localStorageOptOut = _getAndRemoveFromLocalStorage(Constants.OPT_OUT + apiKeySuffix);
463+
if (localStorageOptOut !== null && localStorageOptOut !== undefined) {
464+
localStorageOptOut = String(localStorageOptOut) === 'true'; // convert to boolean
465+
}
466+
467+
// pre-v2.7.0 event and session meta-data was stored in localStorage. move to cookie for sub-domain support
468+
var localStorageSessionId = parseInt(_getAndRemoveFromLocalStorage(Constants.SESSION_ID));
469+
var localStorageLastEventTime = parseInt(_getAndRemoveFromLocalStorage(Constants.LAST_EVENT_TIME));
470+
var localStorageEventId = parseInt(_getAndRemoveFromLocalStorage(Constants.LAST_EVENT_ID));
471+
var localStorageIdentifyId = parseInt(_getAndRemoveFromLocalStorage(Constants.LAST_IDENTIFY_ID));
472+
var localStorageSequenceNumber = parseInt(_getAndRemoveFromLocalStorage(Constants.LAST_SEQUENCE_NUMBER));
473+
474+
var _getFromCookie = function _getFromCookie(key) {
475+
return type(cookieData) === 'object' && cookieData[key];
476+
};
477+
scope.options.deviceId = _getFromCookie('deviceId') || localStorageDeviceId;
478+
scope.options.userId = _getFromCookie('userId') || localStorageUserId;
479+
scope._sessionId = _getFromCookie('sessionId') || localStorageSessionId || scope._sessionId;
480+
scope._lastEventTime = _getFromCookie('lastEventTime') || localStorageLastEventTime || scope._lastEventTime;
481+
scope._eventId = _getFromCookie('eventId') || localStorageEventId || scope._eventId;
482+
scope._identifyId = _getFromCookie('identifyId') || localStorageIdentifyId || scope._identifyId;
483+
scope._sequenceNumber = _getFromCookie('sequenceNumber') || localStorageSequenceNumber || scope._sequenceNumber;
484+
485+
// optOut is a little trickier since it is a boolean
486+
scope.options.optOut = localStorageOptOut || false;
487+
if (cookieData && cookieData.optOut !== undefined && cookieData.optOut !== null) {
488+
scope.options.optOut = String(cookieData.optOut) === 'true';
489+
}
490+
491+
_saveCookieData(scope);
492+
};
493+
433494
/**
434495
* Fetches deviceId, userId, event meta data from amplitude cookie
435496
* @private
@@ -1375,8 +1436,16 @@ AmplitudeClient.prototype._mergeEventsAndIdentifys = function _mergeEventsAndIde
13751436

13761437
// case 3: need to compare sequence numbers
13771438
} else {
1378-
event = this._unsentIdentifys[identifyIndex++];
1379-
maxIdentifyId = event.event_id;
1439+
// events logged before v2.5.0 won't have a sequence number, put those first
1440+
if (!('sequence_number' in this._unsentEvents[eventIndex]) ||
1441+
this._unsentEvents[eventIndex].sequence_number <
1442+
this._unsentIdentifys[identifyIndex].sequence_number) {
1443+
event = this._unsentEvents[eventIndex++];
1444+
maxEventId = event.event_id;
1445+
} else {
1446+
event = this._unsentIdentifys[identifyIndex++];
1447+
maxIdentifyId = event.event_id;
1448+
}
13801449
}
13811450

13821451
eventsToSend.push(event);

src/cookiestorage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ cookieStorage.prototype.getStorage = function() {
5959
opts = opts || {};
6060
this._options.expirationDays = opts.expirationDays || this._options.expirationDays;
6161
// localStorage is specific to subdomains
62-
this._options.domain = opts.domain || this._options.domain || window && window.location && window.location.hostname;
62+
this._options.domain = opts.domain || this._options.domain || (window && window.location && window.location.hostname);
6363
return this._options.secure = opts.secure || false;
6464
},
6565
get: function(name) {

0 commit comments

Comments
 (0)