#ニフティクラウド mobile backendとは
ニフティクラウド mobile backend(以降NCMB)とは、ニフティさんが提供するmBaaSサービスです。
様々なプラットフォームで利用可能であり、UnityにもSDKが提供されています
このNCMB、サービス自体は素晴らしいのですが、 ドキュメントとUnity pluginの使い勝手がクソ です。
自分が踏んだ罠を、共有も兼ねてメモしていきたいと思います。
#メモ
ログイン/サインイン処理をObservable化する
*Asyncシリーズのコールバック引数が 気持ち悪くてありえない 感じになっているので、それを隠蔽してUniRxのIObservableにしました。
別記事にまとめたのでこちらを参考に。
【NCMB】 ニフティクラウド mobile backend のログイン処理をIObservable化してUniRxで扱えるようにする
##ユーザがメールアドレスの確認を行っているか調べる
設定でメールアドレス認証をONにしていて、かつ確認メールをちゃんとユーザが確認したかアプリから取得する方法を調べました。
//ログイン
ObservableNcmbUserAuth.LoginAsync(id, pass)
.Subscribe(user =>
{
//未確認の場合はnull、確認済みの場合はtrue
var isConfirmed = user["mailAddressConfirm"];
//未確認の場合はnull、確認済みの場合はメールアドレス
var mailAddress = user.Email;
});
##ユーザのメールアドレスを再設定する
シンプルにEmail属性を書き換えてSaveすればOK.
アプリケーション設定から確認メールを有効にしていた場合、自動的に確認メールが送信されます。
//userはNCMBUser
user.Email = "newmailaddress@hogehoge.fuga";
user.SaveAsync();
新規ユーザ登録時に Authentication error by header incorrect
というエラーが出てしまう
結論からいうと、「ログアウト」すれば直ります。
デバッグ時に発生しがちなエラー。アプリからユーザ登録した後に、そのユーザを管理コンソールから削除すると発生します。
理由は前のユーザのセッション情報がアプリに残ってしまっており、それでAPIリクエストを行ってしまうから。
参考
void Start()
{
//起動直後にとりあえずログアウトを実行しておけば回避可能
NCMBUser.LogOutAsync();
}
既存の会員ロールにユーザを追加する
これはAPIドキュメントが間違っていて非常にたちが悪いです。 ドキュメントが修正対応されました
APIドキュメントの方法で実行すると、「ロールの新規追加処理」が走ってしまうため、roleName is duplication.
といったエラーが発生してしまいます。
ではどうするのかというと、NCMBRoleをnewを使って取得するのではなく、サーバから取得してあげなくてはいけません。
NCMBRole.GetQuery().FindAsync((roleList, error) =>
{
//roleListの型はList<NCMBRole>
Debug.Log(roleList.Count);
});
//"proPlan"というロールにuserを追加する
NCMBRole.GetQuery().WhereEqualTo("roleName", "proPlan").FindAsync((roleList, error) =>
{
var role = roleList.FirstOrDefault();
role.Users.Add(user);
role.SaveAsync();
});
NCMBRole.GetQuery()
を使えばObjectIdが設定されたNCMBRoleが取得できるので、これを使ってあげれはユーザの追加を行うことができます。
会員ロールにユーザを追加するとOperation is invalid after previous operation.
が発生する
これは UnitySDKのバグ で、該当ロールのレコードが空の場合に発生します。適当にユーザを作ってを該当のロールに入れておけば回避できます。マジかよ。
ACLの設定方法
オブジェクトの権限(ACL)を変更する場合、NCMBObjectのACLを一度取得し、 変更した後に再代入 をしてあげる必要があります。
var acl = user.ACL;
//adminにread権限を追加する
acl.SetRoleReadAccess("admin", true);
user.ACL = acl; //この操作が必要
user.SaveAsync();
理由としては、Save処理はNCMBObjcetの内部状態が変化した時にしか実行されないためです。
そのため、再代入を明示的に行って値が変更したことをNCMBObjectに認識させてあげる必要があります。
ちなみにREST APIで踏んだ罠
権限を不許可にする場合は要素を未指定にしなくてはいけない。
# Read/Write両方を許可したい場合はtrueを指定
'role:Admin' => {
'write' => true,
'read' => true
}
# じゃあread onlyしようと思ってfalseを指定したらエラー
'role:Admin' => {
'write' => false,
'read' => true
}
# ReadOnlyにしたい場合、その要素を指定しないのが正しい
'role:Admin' => {
'read' => true
}
パスワードの再設定を行う
NCMBUser.RequestPasswordResetAsync(string email)
を実行することで、対象のメールアドレスにパスワードリセットメールが送信できる。パスワードの再設定はメールアドレスに記載されたURLにあるForm上で行うことになる。
この方法はメールアドレスが登録されたユーザにしか利用できない。
/// <summary>
/// パスワード再設定を行う
/// </summary>
/// <returns>成功時OnNext 失敗時OnError</returns>
public IObservable<Unit> ResetPassword(string email)
{
return Observable.Create<Unit>(observer =>
{
if (string.IsNullOrEmpty(email))
{
observer.OnError(new Exception("メールアドレスが設定されていません"));
}
else
{
NCMBUser.RequestPasswordResetAsync(email, ex =>
{
if (ex != null)
{
observer.OnError(ex);
}
else
{
observer.OnNext(Unit.Default);
observer.OnCompleted();
}
});
}
return Disposable.Create(() => { });
});
}