Parse Server/JS SDK, ошибка 206 при сохранении пользовательского объекта

У меня возникли проблемы с использованием Parse Server JS SDK для редактирования и сохранения пользователя.

Я вхожу в систему, вхожу в систему и получаю пользователя просто отлично, я могу вызывать без исключения user.set и добавлять/редактировать любое поле, которое хочу, но когда я пытаюсь сохранить, даже при использовании masterKey, я получаю Error 206: Can t modify user <id>.

Я также пытался использовать save для прямой установки полей, тот же результат.

Интересно, что в БД схема пользователя обновляется новыми полями и типами.

Вот моя функция обновления:

function login(user, callback) {
    let username = user.email,
        password = user.password;

    Parse.User.logIn(username, password).then(
        (user) => {
            if(!user) {
                callback('No user found');
            } else {
                callback(null, user);
            }
        },
        (error) => {
            callback(error.message, null);
        }
    );
}

function update(user, callback) {
    login(user, (error, user) => {
        if(error) {
            callback('Can t find user');
        } else {
            console.log('save');
            console.log('Session token: ' + user.getSessionToken());
            console.log('Master key: ' + Parse.masterKey);
            user.set('user', 'set');
            user.save({key: 'test'}, {useMasterKey: true}).then(
                (test) => {
                    console.log('OK - ' + test);
                    callback();
                }, (err) => {
                    console.log('ERR - ' + require('util').inspect(err));
                    callback(error.message);
                }
            );
        }
    });
}

И пример ошибки:

update
save
Session token: r:c29b35a48d144f146838638f6cbed091
Master key: <my master key>
ERR- ParseError { code: 206, message: 'cannot modify user NPubttVAYv' }

Как правильно сохранить отредактированного пользователя?


person DrakaSAN    schedule 25.07.2016    source источник
comment
github.com/ParsePlatform/parse-server/issues/   -  person eggyal    schedule 27.07.2016


Ответы (4)


У меня была точно такая же проблема при использовании Parse Server с перенесенными данными из существующего приложения.

Приложение было создано до марта 2015 года, когда были представлены новые расширенные сеансы. Приложение по-прежнему использовало устаревшие токены сеанса, и переход на новую систему отзываемых сеансов так и не был выполнен. Parse Server требует отзываемых токенов сеанса и не будет работать при обнаружении устаревших токенов сеанса.

В панели настроек приложения параметр Require revocable sessions не был включен до миграции, и сеансы пользователей не переносились в новую систему при переходе на Parse Server. Результатом при попытке редактирования пользователя было 400 Bad Request с сообщением cannot modify user xxxxx (Code: 206).

Чтобы решить эту проблему, я воспользовался руководством по миграции сеансов, предоставленным Parse, в котором объясняется, как выполнить обновление. от устаревших токенов сеанса к отзывным сеансам. В зависимости от ваших потребностей описаны несколько методов, таких как enableRevocableSession(), чтобы включить эти сеансы в мобильном приложении, если у вас есть только веб-приложение, вы можете принудительно заставить любые запросы API с устаревшим токеном сеанса возвращать ошибку invalid session token и т. д.

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

person HiDeo    schedule 28.07.2016
comment
Я создаю приложение с нуля, это не миграция. - person DrakaSAN; 02.08.2016

У меня была такая же ошибка, и у меня не работали ни useMasterKey, ни sessionToken. :( Вот мой код:

        console.log("### attempt 1 sessionToken: " + request.user.getSessionToken());
        var p1 = plan.save();
        var p2 = request.user.save(null,  {sessionToken: request.user.getSessionToken()});
        return Parse.Promise.when([p1, p2]).then(function(savedPlan) {
        ...
        }

Я вижу соответствующий токен сеанса в выводе журнала: 2016-08-21T00:19:03.318662+00:00 app[web.1]: ### attempt 1 sessionToken: r:506deaeecf8a0299c9a4678ccac47126

мой пользовательский объект имеет правильные значения ACL:

"ACL":{"*":{"read":true},"PC7AuAVDLY":{"read":true,"write":true}}

Я также вижу кучу журналов beforeSave и afterSave, в которых пользователь не определен. не уверен, связано ли это.

beforeSave triggered for _User for user undefined:

Я использую последнюю версию парсера-сервера 2.2.18 на Heroku (попробовал на AWS, результаты такие же)

person Quan Ding    schedule 21.08.2016
comment
Вы нашли решение? - person Jugal Desai; 07.12.2016

function login(logInfo, callback) {
    let username = logInfo.email,
        password = logInfo.password;

    Parse.User.logIn(username, password).then(
        (user) => {
            if(!user) {
                callback('No user found');
            } else {
                callback(null, user);
            }
        },
        (error) => {
            callback(error.message, null);
        }
    );
}

function update(userInfo, data, callback) {
    login(userInfo, (error, user) => {
        if(error) {
            callback('Can t find user');
        } else {
            getUpdatedData(user.get('data'), data, (error, updateData) => {
                if(error) {
                    callback(error);
                } else {
                    user.save({data: updateData}, /*{useMasterKey: true}*/ {sessionToken: user.get("sessionToken")}).then(
                        (test) => {
                            callback();
                        }, (err) => {
                            callback(error.message);
                        }
                    );
                }
            });
        }
    });
}

По какой-то причине повторная попытка использовать sessionToken сработала.

person DrakaSAN    schedule 02.08.2016

Это не то, как асинхронные функции работают в JavaScript. Когда createUser возвращается, пользователь еще не создан. Вызов user.save запускает процесс сохранения, но он не завершается до тех пор, пока не будет выполнен обратный вызов успеха или ошибки. Вы должны иметь createUser, принимающий другой обратный вызов в качестве аргумента и вызывающий его из обратного вызова user.save success.

Кроме того, вы не можете создать пользователя с сохранением. Вам нужно использовать Parse.User.signUp.

Функция возвращает значение задолго до успешного или ошибочного вызова.

person Yogesh Rathi    schedule 03.08.2016
comment
В этот момент пользователь уже создан и гарантированно существует в базе данных. Где вы увидели createUser в моем коде? - person DrakaSAN; 03.08.2016