Как объединить данные пользователя после входа в систему?

Не имеет значения, создаете ли вы интернет-магазин или любое другое приложение, которое использует сессию для хранения данных между запросами. Если вы не хотите раздражать пользователя, требуя от него регистрации, вам нужно разрешить ему выполнять определенные задачи анонимно, когда это возможно (у пользователя действительно должна быть причина для регистрации).

Возникает проблема - если пользователь решает войти в систему со своим существующим профилем, он может уже иметь некоторые данные в своем "анонимном" сеансе.

Каковы лучшие практики объединения этих данных? Я предполагаю, что приложение должно объединить его автоматически, где это возможно, или позволить пользователю решить, где это невозможно.

Но я спрашиваю больше, есть ли какие-нибудь ресурсы о том, как эффективно использовать магию в базе данных (где обычно хранятся данные сеанса).

У меня есть два основных решения:

  1. Чтобы сохранить анонимные данные сеанса и просто добавить еще одно "отношение", сообщающее, что на самом деле используется, где и как оно объединяется
  2. Физически объединить эти данные

Можно сказать, что первое решение, вероятно, будет более эффективным, поскольку информация о любом отношении, вероятно, будет означать меньше данных, чем данные о пользователе. Но это также будет означать больше усилий при чтении данных (так как в первую очередь нам нужно прочитать отношение, чтобы получить реальные пользовательские данные).

Существуют ли какие-либо статьи / ресурсы для проектирования структур данных для этого конкретного варианта использования (анонимные + пользовательские данные)?

2 ответа

Решение

Отличный вопрос, который должен задать любой разработчик приложения, использующий пользовательские данные, и, к сожалению, очень немногие это делают:(

На самом деле, здесь есть два совершенно независимых вопроса:

  • Q1 - На каком этапе пользователь должен войти / зарегистрироваться?

  • Q2 - параллелизм данных и разрешение конфликтов (см. Ниже).

И здесь некоторый анализ для каждого из вопросов. Пожалуйста, извините за мою дополнительную страсть из-за моего собственного опыта "разочарованного пользователя".:)


Q1 - это чистый вопрос юзабилити. На что ответ на самом деле очевиден:

  • Избегайте или задерживайте, чтобы заставить пользователя войти в систему как можно больше!

Даже необходимость сохранения государства сама по себе не является достаточной причиной. Если я как пользователь не заинтересован в сохранении этого состояния, не заставляйте меня подписывать! Пожалуйста!

Единственная причина, по которой вы (как веб-сайт) можете заставить меня подписать документ, - это когда я (как пользователь) хочу сохранить свои данные для дальнейшего использования. Здесь я говорю как пользователь, потративший время на подпись, чтобы найти сайт бесполезным. Если вы хотите избавиться от слишком большого количества пользователей, это правильный путь. В любом другом случае - пожалуйста, задержите это как можно больше!

Почему так много сайтов полностью игнорируют такое очевидное правило? Возможные причины, которые я вижу:

  • R1 - дружественный к разработчику и дружественный пользователю. Да, это удобно для разработчиков, так как требует немедленного входа, поэтому нам не нужно беспокоиться о параллелизме (Q2). Таким образом, мы можем сэкономить затраты разработчиков, время и т. Д. Но каждая экономия происходит за счет затрат! Который в этом случае называется User Experience. Который не обязательно, где вы хотели бы искать для экономии. Тем более, что решение не должно быть таким сложным (см. Ниже).

  • R2 - Дизайнер или менеджер, принимающий решение, - это "внутренний энтузиаст":) Она живет счастливой жизнью в окружении сверхбыстрых компьютеров с суперскоростным подключением к Интернету и не может себе представить, что пение может быть настолько сложным для любого пользователя. Так почему же это так важно? Так много причин:

  • Это нарушает поток приложения. Сайты, живущие в прошлом веке, по-прежнему заменяют весь экран иногда довольно длинной формой. Некоторые формы плохо спроектированы, некоторые имеют ошибочные инструкции, некоторые просто не работают. В некоторых есть кнопки отправки, которые по какой-то причине отключены в используемом браузере. У некоторых дизайнеров форм есть гениальная идея заблокировать определенные поля с едва заметным изменением или цветом. Тогда не показывай мне поле, если ты не хочешь, чтобы я его заполнил!

  • Если сайт серьезно относится к данным пользователя, он должен запросить электронную почту и проверить ее! Зачем? Как еще мне вернуться к пользователю, который забыл все остальные учетные данные? Зачем проверять? Что делать, если пользователь неправильно набрал письмо? Если я не проверю это, в следующий раз, когда пользователь попытается восстановить пароль с помощью своего правильного адреса электронной почты, произойдет сбой восстановления, и все данные будут потеряны! Очевидно, что есть сайты, которые не делают этого. Затем мне нужно подождать, пока письмо с подтверждением не будет получено, и нажать, надеюсь, хорошо отформатированную и уникально идентифицируемую ссылку, которая не ломается в моем браузере, или получить несколько забавных символов из-за обнаружения неработающей кодировки, что делает всю ссылку непригодной для использования.

  • Подключение к Интернету может быть медленным или прерванным, что делает каждый следующий шаг болезненным. Даже при хорошем соединении, тут и там, страница внезапно загружается намного дольше. Также электронная почта может не прийти сразу же. Тогда нетерпеливый пользователь начинает яростно нажимать ссылку "отправить подтверждение". В этом случае 90% сайтов повторно отправляют свою ссылку с новым токеном, но также отключают все предыдущие токены. Затем несколько писем приходят в непредсказуемом порядке, и бедный пользователь должен напрасно угадать, какое из них (и только одно) все еще действует. Теперь, почему этим сайтам так сложно поддерживать активными несколько токенов, просто для моего случая.

  • Наконец, до сих пор существует такая сложная привычка для сайтов настаивать на так называемом "имени пользователя". Так что теперь, помимо моей электронной почты, я должен подумать, чтобы придумать это уникальное имя пользователя, отличное от любого предыдущего пользователя! Большое вам спасибо за то, что сделали это сладким и легким! Мой собственный способ справиться с этим - использовать мою электронную почту в качестве имени пользователя. К сожалению, есть еще сайты, которые не принимают его! Тогда что, если какой-нибудь забавный тип использовал мою электронную почту в качестве своего имени пользователя? Не так нереально, если ваш адрес электронной почты bill@gates.com. Но почему бы просто не использовать электронную почту и пароль, чтобы избежать всего этого беспорядка?


Вот несколько возможных рекомендаций по облегчению боли пользователя:

  • Заставьте меня войти / зарегистрироваться, если вам это абсолютно необходимо, и дайте мне возможность не делать этого!

  • Сделайте это одной страницей формы, чтобы я знал, что я собираюсь сделать, и, разумеется, используйте как можно меньше полей ввода. В идеале только электронная почта и пароль (возможно, дважды), без имени пользователя!

  • Покажите свою форму входа в виде небольшого окна в верхней части страницы без перезагрузки, и позвольте мне избавиться от нее одним щелчком мыши вдали от этого окна. Не заставляйте меня искать кнопку "Закрыть" или, что еще хуже, значок, который я могу спутать с чем-то другим!

  • Аккаунт для пользователя, чтобы нажимать вперед / назад и перезагрузить кнопки. Не очищайте форму после перезагрузки! Не ставьте кнопку очистки вообще! Слишком легко нажать случайно. Данные, которые вы просите меня заполнить, не должны быть такими длинными, чтобы я не мог их повторно ввести без необходимости "помощи" для очистки.


Теперь к вопросу Q2. Здесь у нас есть хорошо известная проблема разрешения конфликтов, которая возникает всякий раз, когда необходимо объединить две данные. Например, анонимные данные и данные зарегистрированных пользователей, а также всякий раз, когда два пользователя изменяют одни и те же данные, или один и тот же пользователь изменяет их с разных устройств в разное время, или локально сохраненные данные конфликтуют с данными сервера и так далее.

Но каков бы ни был источник, проблема всегда одна и та же. У нас есть две данные, скажем, два объекта $obj1 и $obj2, и вам нужно создать один объединенный объект $obj3. Логика может быть такой же простой, как правило, что объект сервера всегда выигрывает, или что последний измененный объект всегда выигрывает, или ключи последнего измененного объекта всегда выигрывают, или любая более сложная логика. Это действительно зависит от характера вашего приложения. Но в каждом случае все, что вам нужно сделать, это написать свою логическую функцию с аргументами $obj1, $obj2, которая возвращает $obj3.

Решение, которое, возможно, будет работать во многих случаях, состоит в том, чтобы сохранить метку времени для каждого атрибута (ключа) объекта и позволить последнему измененному ключу выиграть в момент синхронизации. Это объясняет, например, ситуацию, когда один и тот же пользователь изменяет различные атрибуты, будучи анонимным с разных устройств.

Представьте, что я вчера изменил ключи A и B на устройстве AA, затем вошел в систему сегодня с устройства BB, чтобы ввести другой B и сохранил его на сервере, а затем переключился обратно на свое устройство AA, где я являюсь анонимным, чтобы ввести еще один A без изменений старый B со вчерашнего дня, а затем понял, что я хочу войти и синхронизировать. Тогда мой локальный B явно старый и явно не должен перезаписывать значение B, которое я недавно изменил на устройстве BB. В этом, казалось бы, сложном случае вышеприведенные решения работают эффективно и без проблем. Напротив, ставить отметку времени только на целые объекты было бы неправильно.

Теперь в некоторых случаях может иметь смысл сохранять оба объекта и, например, различать их, добавляя дополнительные свойства, как в случае 1, предложенном в вопросе Радека. Например, Dropbox добавляет что-то вроде "конфликтующая копия пользователя X" в конец файла. Как и в случае с Dropbox, это целесообразно в случае приложений для совместной работы, где пользователям нравится иметь контроль версий. Однако в этих случаях вы, как разработчик, просто сохраняете две копии и позволяете пользователям справиться с этой проблемой.

Если, с другой стороны, вам нужно написать сложную логику, основанную на данных пользователя, иметь две разные копии висящих вокруг может быть кошмаром. В этом случае я бы разделил данные на две группы (например, создал два объекта из одного). Первая группа имеет данные, представляющие состояние приложения в целом, что важно, чтобы быть уникальным. Для этих данных я бы использовал разрешение конфликта, как указано выше или подобное. Тогда вторая группа зависит от пользователя, где я буду хранить обе данные как две отдельные записи в базе данных, правильно отмечать их (как это делает Dropbox), а затем разрешать пользователям работать со списком из двух (или более) записей их проекта.,

Наконец, если это дополнительное усложнение управления базами данных делает разработчика неудобным, и поскольку Radek попросил дать ссылку на ресурс, я хочу "убить двух мух одним выстрелом", упомянув запись в блоге StackMob offline Sync, решение которой предоставляет как базу данных, так и Функциональность управления пользователями и так избавляет разработчика от этой боли. Конечно, можно найти гораздо больше информации при поиске совпадений данных, разрешения конфликтов и тому подобного.

В заключение я должен добавить обязательный отказ от ответственности, что все написанное здесь - просто мои собственные мысли и предложения, которые каждый должен использовать на свой страх и риск, и не возлагать на меня ответственность, если вдруг у вас слишком много счастливых пользователей, делающих сбой вашей системы:)

Поскольку я сам работаю над приложением, в котором я реализую все эти аспекты, мне, безусловно, очень интересно услышать другие мнения и то, что еще люди могут сказать по этому вопросу.

Исходя из моего опыта - как пользователя сайтов, требующих входа в систему, так и разработчика, работающего с зарегистрированными пользователями, - я не думаю, что когда-либо видел, чтобы сайт вел себя так.

Обычный шаблон - позволить пользователю быть анонимным, и в первый раз, когда он делает что-то, что потребует сохранения состояния, ему предлагается войти в систему. Затем предыдущее действие запоминается, и пользователь может продолжить. Например, если они пытаются добавить что-то в свою корзину, им предлагается войти в систему, а затем после входа товар попадает в их корзину.

Я предполагаю, что некоторые места позволят вам заполнить корзину, а затем войти в систему, после чего корзина будет привязана к конкретному пользователю.

Я хотел бы создать объект SessionUser, который имеет состояние взаимодействия с сайтом и одно поле с именем UserId, которое используется для получения других вещей, таких как имя, адрес и т. Д.

Для анонимных пользователей я бы создал объект SessionUser с пустой ссылкой на UserId. Это означает, что мы не можем разрешить имя или адрес, но мы все еще можем сохранить состояние. Действия, которые они выполняют, страницы, которые они просматривают и т. Д.

После того как они войдут в систему, нам не нужно объединять два объекта, мы просто заполняем поле UserId в SessionUser, и теперь мы можем пройти по графу объектов, чтобы получить имя, адрес электронной почты, адрес или что-то еще.

Другие вопросы по тегам