firebase 将用户添加到现有组

gcuhipw9  于 2022-12-04  发布在  其他
关注(0)|答案(2)|浏览(198)

我试图使一个跟踪器应用程序中,我一个用户可以创建一个组,当点击“显示在Map上”,它会显示所有成员的位置。我做了组信息页面中,有一个添加成员按钮。当点击它把用户带到一个新的页面。在这个新的页面中,他搜索一个不同的用户女巫,他想添加。点击TextFormField下的搜索图标时,会出现一个ListTile。点击该ListTile时,搜索到的用户应被添加到该组,搜索者应被重定向回组信息页面。
我在尝试将用户添加到现有组时遇到了问题,但我得到了一个错误:
状态错误:DocumentSnapshotPlatform中不存在字段。
下面是向组中添加不同用户的代码

import 'package:cloud_firestore/cloud_firestore.dart';

class DatabaseService {
  final String? uid;
  DatabaseService({this.uid});

  // reference for collection
  final CollectionReference userCollection =
      FirebaseFirestore.instance.collection("users");
  final CollectionReference groupCollection =
      FirebaseFirestore.instance.collection("groups");

  // saving the user data
  Future savingUserData(String name, String email) async {
    return await userCollection.doc(uid).set({
      "name": name,
      "email": email,
      "friends": [],
      "groups": [],
      "profilePicture": "",
      "uid": uid,
      "latitude": "",
      "longitude": "",
    });
  }

  //getting user data
  Future gettingUserData(String email) async {
    QuerySnapshot snapshot =
        await userCollection.where("email", isEqualTo: email).get();
    return snapshot;
  }


  // create a group
  Future createGroup(String name, String groupName, String id) async {
    DocumentReference groupDocumentReference = await groupCollection.add({
      "groupName": groupName,
      "groupIcon": "",
      "groupCreator": "",
      "admins": [],
      "members": [],
      "groupId": "",
    });

    await groupDocumentReference.update({
      "admins": FieldValue.arrayUnion(["${uid}_$name"]),
      "groupCreator": FieldValue.arrayUnion(["${id}_$name"]),
      "groupId": groupDocumentReference.id
    });

    DocumentReference userDocumentReference = userCollection.doc(uid);
    return await userDocumentReference.update({
      "groups":
          FieldValue.arrayUnion(["${groupDocumentReference.id}_$groupName"])
    });
  }

  getUserGroups() async {
    return userCollection.doc(uid).snapshots();
  }

  //search
  searchByEmail(String userEmail) async {
    return userCollection.where('email', isEqualTo: userEmail).get();
  }


  //get group admins
  getGroupAdmins(String groupId) async {
    return groupCollection.doc(groupId).snapshots();
  }

  getGroupMembers(String groupId) async {
    return groupCollection.doc(groupId).snapshots();
  }

  Future addMember(
    String groupId,
    String groupName,
    String memeberId,
    memberName,
  ) async {
    DocumentReference userDocumentReference = userCollection.doc(memeberId);
    DocumentReference groupDocumentReference = groupCollection.doc(groupId);

    DocumentSnapshot userdocumentSnapshot = await userDocumentReference.get();
    List<dynamic> groups = await userdocumentSnapshot['groups'];

    DocumentSnapshot groupDocumentSnapshot = await groupDocumentReference.get();
    List<dynamic> members = await groupDocumentSnapshot['members'];

    if (groups.contains("${groupId}_$groupName") &
        members.contains("${memeberId}_$memberName")) {
      return null;
    } else {
      await groupCollection.doc(groupId).update({
        "members": FieldValue.arrayUnion(["${memeberId}_$memberName"])
      });
    }
  }

 
}

这是添加成员页面

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:tracker_app/page_changer/page_changer.dart';
import 'package:tracker_app/pages/app_pages/info_page.dart';
import 'package:tracker_app/services/database_service.dart';

import '../../theme/theme.dart';

class AddMembers extends StatefulWidget {
  final String groupId;
  final String groupName;
  const AddMembers({super.key, required this.groupId, required this.groupName});

  @override
  State<AddMembers> createState() => _AddMembersState();
}

class _AddMembersState extends State<AddMembers> {
  QuerySnapshot? searchSnapshot;

  TextEditingController emailController = TextEditingController();

  String email = "";
  String friendId = "";
  String friendName = "";

  bool isLoading = false;
  bool hasUserSearched = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          "Add members",
          style: TextStyle(fontSize: 30, fontWeight: FontWeight.w500),
        ),
        centerTitle: true,
      ),
      body: SingleChildScrollView(
        child: Column(children: [
          const Divider(
            height: 5,
            indent: 5,
            endIndent: 5,
            thickness: 1.5,
          ),
          Container(
            height: 10,
          ),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10),
            child: TextFormField(
              controller: emailController,
              cursorColor: AppColors.secondary,
              decoration: InputDecoration(
                  errorBorder: OutlineInputBorder(
                      borderSide: const BorderSide(color: Colors.red),
                      borderRadius: BorderRadius.circular(50)),
                  focusedBorder: OutlineInputBorder(
                      borderSide: const BorderSide(
                        color: AppColors.secondary,
                      ),
                      borderRadius: BorderRadius.circular(50)),
                  enabledBorder: OutlineInputBorder(
                      borderSide: const BorderSide(
                        color: AppColors.secondary,
                      ),
                      borderRadius: BorderRadius.circular(50)),
                  labelText: "email",
                  labelStyle: const TextStyle(
                    color: AppColors.secondary,
                    fontWeight: FontWeight.w500,
                  ),
                  suffixIcon: InkWell(
                    splashColor: AppColors.secondary,
                    borderRadius: BorderRadius.circular(360),
                    onTap: () {
                      initiateSearchMethod();
                    },
                    child: const Icon(
                      Icons.search,
                      color: AppColors.secondary,
                    ),
                  ),
                  hintText: "Enter persons email"),
              onChanged: (value) {
                setState(() {
                  email = value;
                });
              },
            ),
          ),
          userList(),
        ]),
      ),
    );
  }

  initiateSearchMethod() async {
    if (emailController != null) {
      setState(() {
        isLoading = true;
      });
      await DatabaseService(uid: FirebaseAuth.instance.currentUser!.uid)
          .searchByEmail(email)
          .then((snapshot) {
        setState(() {
          searchSnapshot = snapshot;
          isLoading = false;
          hasUserSearched = true;
          friendId = snapshot!.docs[0]['id'];
          friendName = snapshot!.docs[0]['name'];
        });
      });
    }
  }

  userList() {
    return hasUserSearched
        ? ListView.builder(
            shrinkWrap: true,
            itemCount: searchSnapshot!.docs.length,
            itemBuilder: (context, index) {
              return friendSearchTile();
            },
          )
        : Container();
  }

  friendSearchTile() {
    // check if user is friend
    //GdzhH8YGCsTMhmPf6aAeXvb09GH3

    return ListTile(
      leading: CircleAvatar(
        radius: 25,
        backgroundColor: AppColors.secondary,
        child: Text(
            searchSnapshot!.docs[0]['name'].substring(0, 1).toUpperCase(),
            style: const TextStyle(color: Colors.white)),
      ),
      title: Text(friendName),
      subtitle: Text(searchSnapshot!.docs[0]['email']),
      trailing: InkWell(
        borderRadius: BorderRadius.circular(360),
        onTap: () {
          DatabaseService(uid: FirebaseAuth.instance.currentUser!.uid)
              .addMember(
                  widget.groupId,
                  widget.groupName,
                  searchSnapshot!.docs[0]['id'],
                  searchSnapshot!.docs[0]['name']);
          nextScreenReplace(context,
              InfoPage(groupName: widget.groupName, groupId: widget.groupId));
          print("friendId: $friendId");
        },
        splashColor: AppColors.secondary,
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
          child: const Icon(
            Icons.add,
          ),
        ),
      ),
    );
  }
}
5n0oy7gb

5n0oy7gb1#

经过更多的搜索,我找到了解决方案。在AddMembers页面,当点击添加一个用户时,需要groupId,groupName,friendId(用户ID),friendName(朋友名称)。问题出在firendId。行searchSnapshot!.docs[0]['id]是错误的。在firebase中,我将用户ID标记为“uid”。更改后,它开始工作。行:

DatabaseService(uid: FirebaseAuth.instance.currentUser!.uid)
              .addMember(
                  widget.groupId,
                  widget.groupName,
                  searchSnapshot!.docs[0]['id'],
                  searchSnapshot!.docs[0]['name']);

我改口:

DatabaseService(uid: FirebaseAuth.instance.currentUser!.uid)
              .addMember(
                  widget.groupId,
                  widget.groupName,
                  searchSnapshot!.docs[0]['uid'],
                  searchSnapshot!.docs[0]['name']);
brjng4g3

brjng4g32#

问题似乎出在如何从DocumentSnapshot对象获取用户和组文档的组和成员数组上。在addMember()函数中,使用await关键字从DocumentSnapshot对象获取组和成员字段的值,但这些字段不是异步的,因此对它们使用await将不起作用。
要解决此问题,只需在获取组和成员字段的值时删除await关键字,如下所示:

List<dynamic> groups = userdocumentSnapshot['groups'];
List<dynamic> members = groupDocumentSnapshot['members'];

然后,您可以在群组和成员清单上使用contains()方法,检查它们是否已经包含新成员和群组,如果清单中还不存在新成员和群组,则将新成员加入至群组。
以下是进行这些更改后addMember()函数的外观:

Future addMember(
    String groupId,
    String groupName,
    String memeberId,
    memberName,
  ) async {
    DocumentReference userDocumentReference = userCollection.doc(memeberId);
    DocumentReference groupDocumentReference = groupCollection.doc(groupId);

    DocumentSnapshot userdocumentSnapshot = await userDocumentReference.get();
    List<dynamic> groups = userdocumentSnapshot['groups'];

    DocumentSnapshot groupDocumentSnapshot = await groupDocumentReference.get();
    List<dynamic> members = groupDocumentSnapshot['members'];

    if (!groups.contains("${groupId}_$groupName") ||
        !members.contains("${memeberId}_$memberName")) {
      await groupCollection.doc(groupId).update({
        "members": FieldValue.arrayUnion(["${memeberId}_$memberName"])
      });
    }
  }

我希望这对你有帮助!

相关问题