flutter - Flutter Firestore 身份验证
问题描述
我有一个使用 cloud_firestore 插件进行数据访问的 Flutter 项目。用户对应用程序进行身份验证后,我需要做什么才能将其设置为 Firestore 客户端使用的身份验证?例如,我只启用了这些基本规则:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, update, delete: if request.auth.uid == userId;
allow create: if request.auth.uid != null;
}
match /users/{userId}/{document=**} {
allow read, update, delete, create: if request.auth.uid == userId;
}
match /ingredients/* {
allow read, create: if request.auth.uid != null;
}
match /units/* {
allow read, create: if request.auth.uid != null;
}
match /recipes/* {
allow read, create, update: if request.auth.uid != null;
}
}
}
一旦我启用了这些规则,我的 Flutter 应用程序的每个请求都开始失败。如果我用他们拥有的小“模拟器”测试 Firestore 规则,它们会按预期工作,因此从 Flutter 应用程序端似乎没有正确设置身份验证。
编辑:添加一些代码示例。
我有使用 Google Auth 的身份验证代码,所以当用户登录时,它看起来像这样:
class Auth implements AuthService {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: [
'email',
'https://www.googleapis.com/auth/contacts.readonly',
],
);
Future<String> signInWithGoogle() async {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
final FirebaseUser user = await _firebaseAuth.signInWithCredential(credential);
return user.uid;
}
我已经验证了用户的身份验证是否正确。
然后,在访问 Firestore 时,类似:
DocumentSnapshot userSnapshot = await Firestore.instance
.collection('users')
.document(userId)
.collection('shoppingLists')
.document(listName)
.get();
我已经按照所有指南将 Firebase 和 Firestore 添加到我的应用程序中,但我没有看到任何关于将当前经过身份验证的用户设置为发出 Firestore 请求的用户的具体内容,所以我觉得我在那里遗漏了一些东西. 在进行 Firestore 查询以传递当前用户时,我应该做些什么?
解决方案
答案是非用户,因为Firestore.instance
这会给您一个与您的应用断开连接的实例Firebase
;
而是使用创建提供所有密钥的 Firebase 应用程序,然后针对该应用程序进行身份验证,然后针对该应用程序创建一个 Firestore 实例。无法显式传递用户,但代码在内部使用一些逻辑来确定已针对您创建的应用程序进行身份验证的用户。这是我使用的代码:
Future<void> _authenticate() async {
FirebaseApp _app = await FirebaseApp.configure(
name: 'some-name',
options: FirebaseOptions(
googleAppID: 'some:id',
gcmSenderID: 'sender',
apiKey: 'api-key-goes-here',
projectID: 'some-id',
),
);
final _auth = FirebaseAuth.fromApp(_app);
final _result = await _auth.signInAnonymously();
setState(() {
app = _app;
auth = _auth;
user = _result.user;
store = Firestore(app: app); //this is the code that does the magic!
});
}
至于服务器端规则配置 - 参考@cloudwalker's answer