Xamarin调用Firebase认证方法访问受保护实时数据库报错排查
报错核心原因
异常是API调用方式错误直接导致的:
SignInWithOAuthAsync仅适用于Google、Facebook、Microsoft这类第三方OAuth协议的登录场景- 邮箱密码登录不属于OAuth登录流程,你传入
FirebaseAuthType.EmailAndPassword调用这个方法,正好触发了报错提示里的限制:邮箱认证类型不能按此方式使用,请调用邮箱密码认证对应的专属方法
除此之外你的代码还有3个逻辑问题,就算解决了方法调用错误,也会被安全规则拦截无法写入数据:
- 从本地缓存读取历史登录凭证后,不需要重复走登录流程,只需要刷新过期令牌即可
- 初始化
FirebaseClient时没有传入当前用户的认证令牌,服务端会把请求判定为未登录用户发起 - 写入数据时写死了子节点
some uid1,和当前登录用户的UID不匹配,不符合你配置的安全规则要求(规则要求users/$uid路径下只有UID和$uid完全一致的登录用户才有读写权限)
正确实现代码
1. 认证逻辑修正
首次邮箱密码登录调用专属方法,本地有历史凭证时直接刷新令牌,不要调用OAuth相关接口:
private async void Button_Clicked(object sender, EventArgs e) { try { var authProvider = new FirebaseAuthProvider(new FirebaseConfig(你的WebApiKey)); FirebaseAuth currentAuth; // 读取本地缓存的历史凭证 if (Preferences.ContainsKey("MyFirebaseRefreshToken")) { var savedAuthJson = Preferences.Get("MyFirebaseRefreshToken", ""); var savedAuth = JsonConvert.DeserializeObject<FirebaseAuth>(savedAuthJson); // 刷新过期令牌,无需重复登录 currentAuth = await authProvider.RefreshAuthAsync(savedAuth); } else { // 首次邮箱密码登录,调用专属登录方法 currentAuth = await authProvider.SignInWithEmailAndPasswordAsync(输入的邮箱, 输入的密码); // 持久化存储凭证,下次启动直接使用 Preferences.Set("MyFirebaseRefreshToken", JsonConvert.SerializeObject(currentAuth)); } // 初始化数据库客户端时传入认证令牌 var firebaseClient = new FirebaseClient( 你的RealtimeDatabase连接地址, new FirebaseOptions { AuthTokenAsyncFactory = () => Task.FromResult(currentAuth.FirebaseToken) }); // 写入数据时使用当前登录用户的真实UID,匹配安全规则 var currentUserUid = currentAuth.User.LocalId; await firebaseClient.Child("users").Child(currentUserUid).PutAsync(new userinfo { firstName = "dtox", secondName = "solo" }); recordData.Text = ""; } catch(Exception ex) { await App.Current.MainPage.DisplayAlert("Alert", ex.Message, "OK"); } }
注意事项
- 只有对接第三方OAuth身份提供商时才可以使用
SignInWithOAuthAsync方法,邮箱密码、手机号登录都有对应的专属接口,不要混用 - Firebase生成的ID令牌默认有效期为1小时,
RefreshAuthAsync会自动换取新的有效令牌,不需要每次启动都要求用户重新输入账号密码 - 你配置的安全规则是用户私有数据隔离规则,
users节点下的子路径名必须和对应用户的UID完全一致,才会授予读写权限,不要硬编码其他UID值
内容的提问来源于stack exchange,提问作者dtox
相关产品推荐
相关产品推荐

