⚰️

【Flutter×Firebase】ユーザーのブロック機能の実装

2022/03/24に公開約3,700字

記事を書く経緯

Appleからアプリを提出した際、投稿系のアプリは「通報機能、ブロック機能」を搭載してくださいとのこと。

アプリ設計について

画面の状態管理にProviderを使用。
データベースはFirebaseを使用。
今回Firebaseのコレクション名はpostuserlistとします。

目的

1、あなたはユーザー間で行う、「何らか」の投稿アプリの作ろうとしています。
2、Cardと言うWidgetにユーザの情報が記載されている。
3、2のCard付近のElevatedButton(ブロック)を押し、投稿者情報がブロックリストに入る。
投稿者情報が入っていたら、Visibilityの中身が読み込まれ、uidが含まれているか、いないかをcontainsで判別する(trueかfalse)。

View側

class PostUserListPage extends StatelessWidget {
     Visibility(
       // containsを使用すると、blockIdsにcoordinateのuidが含まれているか、いないか
       //判別できる(trueかfalse)
     visible: !(model.blockIds?.contains(post.uid) ?? false),
       child: Card(
          color: Colors.white,
              ElevatedButton(
               child: Text('ブロック',style: TextStyle(color: Colors.white,),),
       onPressed: () async {
            final userId = post.uid;
                print('userId; $userId');
                     await blockUserDialog(
                       context, post, model);
       }
Future blockUserDialog(
      BuildContext context,
      Post post,
      PostUserListModel model,) {
    return showDialog(
      context: context,
      barrierDismissible: false,
      builder: (_) {
        return AlertDialog(
          title: Text("ブロックの確認"),
          content: Text('この投稿ユーザーをブロックしますか?'),
          actions: [
            TextButton(
              child: Text("いいえ"),
              onPressed: () => Navigator.pop(context),
            ),
            TextButton(
              child: Text("はい"),
              onPressed: () async {
                final userId = post.uid;
                print('userId; $userId');
                await model.blockUser(userId);
                Navigator.pop(context);
                final snackBar = SnackBar(
                  backgroundColor: Colors.black,
                  content: Text('投稿者をブロックしました'),
                );
                model.fechPostUserList();
                ScaffoldMessenger.of(context).showSnackBar(snackBar);
              },
            ),
          ],
        );
      },
    );
  }

投稿者リストのクラスを作る

Postと言うクラスを作成し、投稿者の情報(uid)を記述。

class Post {
  Post(
      this.uid,
      );
      String uid;
     }

Model側

Model側でfechPostUserList() というメソッドを用意。
投稿者の情報を取得する。

class PostUserListModel extends ChangeNotifier {
List<Post>? post;

//Firebaseと繋ぐ際はFutureを付ける
  Future<void> fechPostUserList() async {
    final QuerySnapshot snapshot =
    await FirebaseFirestore.instance.collection('postuserlist').get();

    final List<Post> coordinate = snapshot.docs.map((
        DocumentSnapshot document) {
      Map<String, dynamic> data = document.data() as Map<String, dynamic>;

      final String uid = data['uid'];
      
      return Post(
        uid,
	 );
	}).toList();
	
	this.post = post;
	notifyListeners();
	}

ブロックボタンを押したら、投稿者情報がFirebaseblocksコレクションに入る。

Future<void> blockUser(userId) async {
    final uid = FirebaseAuth.instance.currentUser!.uid;
    FirebaseFirestore.instance.collection('blocks')
        .doc(uid).set(
      {
        'blockUserId' : userId,
      }
    );
    notifyListeners();
  }

クエリでブロックしているuidを絞り込む

List<String>? blockIds;

Future<void> blockList(uid) async {
    final QuerySnapshot snapshot =
    await FirebaseFirestore.instance.collection('blocks')
        .where('blockUserId', isNotEqualTo: uid) // 〜と等しくない
        .get();

    final List<String>? blockIds = snapshot.docs.map((
        DocumentSnapshot document) {
      Map<String, dynamic> data = document.data() as Map<String, dynamic>;

      final String blockUserId = data['blockUserId'];
      return (
        blockUserId
      );
    }).toList();

    this.blockIds = blockIds;
    notifyListeners();
  }

Discussion

ログインするとコメントできます