尽管添加了安全规则,如何遇到cloud firestore错误

问题描述 投票:0回答:1

我是 Flutter x Firebase 的初学者,过去三天一直被困在这里。请帮我解决这个问题,并解释一下原因

/Firestore(30190): (25.0.0) [Firestore]: 侦听查询(target=Query( collectionGroup=leaves where status==pending order by name);limitType=LIMIT_TO_FIRST) 失败: Status{code=PERMISSION_DENIED ,描述=权限缺失或不足。,原因=空}

我的代码:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

class AdminDashboardScreen extends StatefulWidget {
  const AdminDashboardScreen({super.key});

  @override
  _AdminDashboardScreenState createState() => _AdminDashboardScreenState();
}

class _AdminDashboardScreenState extends State<AdminDashboardScreen> {
  bool isAdmin = false;
  Future<bool> _isAdmin(String uid) async {
    var doc = await FirebaseFirestore.instance.collection('admins').doc(uid).get();
    return doc.exists;
  }

  @override
  void initState() {
    super.initState();
    _checkIfAdmin();
  }

  Future<void> _checkIfAdmin() async {
    String uid = FirebaseAuth.instance.currentUser!.uid;
    bool admin = await _isAdmin(uid);
    setState(() {
      isAdmin = admin;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (!isAdmin) {
      return Scaffold(
        appBar: AppBar(
          title: Text('Admin Panel'),
        ),
        body: Center(child: Text('You do not have admin privileges.')),
      );
    }
return Scaffold(
  appBar: AppBar(
    title: Text('Admin Panel'),
  ),
  body: StreamBuilder(
    stream: FirebaseFirestore.instance.collectionGroup('leaves')
        .where('status', isEqualTo: 'pending').snapshots(),
    builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) {
        return Center(child: CircularProgressIndicator());
      }
      if (snapshot.hasError) {
        return Center(child: Text('Error: ${snapshot.error}'));
      }
      if (!snapshot.hasData || snapshot.data!.docs.isEmpty) {
        return Center(child: Text('No pending leave requests.'));
      }

      var leaveRequests = snapshot.data!.docs;
      return ListView.builder(
        itemCount: leaveRequests.length,
        itemBuilder: (context, index) {
          var leave = leaveRequests[index];
          return ListTile(
            title: Text('${leave['studentName']} is requesting for a leave'),
            subtitle: Text('Reason: ${leave['reason']}'),
            trailing: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                IconButton(
                  icon: Icon(Icons.check),
                  onPressed: () => _updateLeaveStatus(leave, 'approved'),
                ),
                IconButton(
                  icon: Icon(Icons.close),
                  onPressed: () => _updateLeaveStatus(leave, 'rejected'),
                ),
              ],
            ),
          );
        },
      );
    },
  ),
);

}

void _updateLeaveStatus(QueryDocumentSnapshot leave, String status) async {
    try {
      await leave.reference.update({'status': status});
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Leave request $status')));
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error updating status: $e')));
    }
  }
}

我的数据库安全规则:

    rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Allow only authenticated users to read/write their own documents
    match /students/{studentId}/{documents=**} {
      allow read, write: if request.auth != null && request.auth.uid == studentId;
    }

    // Admin collection
    match /admins/{adminId} {
      allow read, write: if request.auth != null && request.auth.uid == adminId;
    }

    // Allow admins to read and write any student data
    match /students/{studentId}/{documents=**} {
      allow read, write: if request.auth != null && isAdmin(request.auth.uid);
    }
  }
}
flutter firebase google-cloud-firestore firebase-security
1个回答
0
投票

您的安全规则也在此处调用

isAdmin
函数:

match /students/{studentId}/{documents=**} {
  allow read, write: if request.auth != null && isAdmin(request.auth.uid);
}

isAdmin
未在您显示的安全规则中定义,因此调用将失败。请记住,您的安全规则在 Flutter 代码之外的其他地方运行,因此规则无法调用 Flutter 代码中的函数。

如果您希望安全规则能够测试某人是否是管理员,您还必须在规则中编写

isAdmin
实现。

© www.soinside.com 2019 - 2024. All rights reserved.