質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

2回答

649閲覧

Flutterでのいいね機能の開発

ituking

総合スコア80

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2023/08/12 08:47

編集2023/08/13 15:03

実現したいこと

  • エラーを解消させて、いいね機能を実現させたい。

前提

FlutterでSNSを開発しており、いいね機能を開発中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════ The following UnsupportedError was thrown while handling a gesture: Unsupported operation: Cannot add to an unmodifiable list When the exception was thrown, this was the stack: #0 UnmodifiableListMixin.add (dart:_internal/list.dart:114:5) #1 _LikeButtonState.toggleLike.<anonymous closure> (package:chat_app/utils/like_button.dart:28:34) #2 State.setState (package:flutter/src/widgets/framework.dart:1139:30) #3 _LikeButtonState.toggleLike (package:chat_app/utils/like_button.dart:18:5) #4 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1154:21) #5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:275:24) #6 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:654:11) #7 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:311:5) #8 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:281:7) #9 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:167:27) #10 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:469:20) #11 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:445:22) #12 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:331:11) #13 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:400:7) #14 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:363:5) #15 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:320:7) #16 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:293:9) #17 _invoke1 (dart:ui/hooks.dart:158:13) #18 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:382:7) #19 _dispatchPointerDataPacket (dart:ui/hooks.dart:91:31) Handler: "onTap" Recognizer: TapGestureRecognizer#51590 ════════════════════════════════════════════════════════════════════════════════════════════════════

該当のソースコード

like_button.dart

1import 'package:chat_app/model/post.dart'; 2import 'package:flutter/cupertino.dart'; 3import 'package:flutter/foundation.dart'; 4import 'package:flutter/material.dart'; 5 6class LikeButton extends StatefulWidget { 7 final Post post; 8 const LikeButton({super.key, required this.post}); 9 10 @override 11 State<LikeButton> createState() => _LikeButtonState(); 12} 13 14class _LikeButtonState extends State<LikeButton> { 15 bool isLiked = false; 16 17 void toggleLike() { 18 setState(() { 19 List<String> updatedLikedUserIds = List.from(widget.post.likedUserIds); 20 if (kDebugMode) { 21 print("postAccountId: ${widget.post.postAccountId}"); 22 print("likedUserIds: ${widget.post.likedUserIds}"); 23 } 24 if (isLiked) { 25 widget.post.likedUserIds.remove(widget.post.postAccountId); 26 widget.post.likedCount--; 27 } else { 28 widget.post.likedUserIds.add(widget.post.postAccountId); 29 widget.post.likedCount++; 30 } 31 widget.post.likedUserIds = updatedLikedUserIds; 32 if (kDebugMode) { 33 print("updatedLikedUserIds: $updatedLikedUserIds"); 34 print("widget.post.likedUserIds: ${widget.post.likedUserIds}"); 35 } 36 isLiked = !isLiked; 37 }); 38 } 39 40 @override 41 Widget build(BuildContext context) { 42 return IconButton( 43 icon: Icon( 44 Icons.thumb_up_outlined, 45 color: isLiked 46 ? const Color.fromRGBO(255, 100, 130, 1) 47 : CupertinoColors.black, 48 ), 49 onPressed: toggleLike, 50 ); 51 } 52} 53

試したこと

1、以下のページのフォロー、アンフォロー機能を参考にして、
Firestoreに格納された値を表示させるところまでを実装。
https://www.udemy.com/course/flutterfirebasesns/learn/lecture/33363594#overview

2、いいねアイコンをタップで状態管理かつ、値を変化させたいと思い、LikeButtonクラスのtoggleLikeメソッドを実装。以下のページを参考にしました。
https://reigle.info/entry/2022/10/08/100000
https://atsu-developer.net/1114/

3、いいねアイコンをタップしても、いいねアイコンの状態が切り替わることがなく、値も変化しないため一日中デバッグを試みていたが、解決せず。エラーメッセージでググり、以下のページにヒット。
https://stackoverflow.com/questions/57549163/flutter-unsupported-operation-cannot-add-to-an-unmodifiable-list

4、とりあえずlikedUserIdsフィールドが、
Unmodifiable(変更不可能な)リストなのでaddやremoveは実行できませんというエラーというのはわかるので、likefUserIdsの定義方法変えた方が良いかなと思っています。
https://zenn.dev/batacon/articles/44dff583ace01f

5、likedUserIdsの定義時にconstで定義してしまっていることが原因かもしれないと考えています。
https://mebee.info/2022/10/30/post-84218/

補足情報(FW/ツールのバージョンなど)

[✓] Flutter (Channel stable, 3.10.5, on macOS 13.4 22F66 darwin-x64,
locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version
32.1.0-rc1)
[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.79.2)
[✓] Connected device (3 available)
[✓] Network resources

現在の状況

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

likedUserIds定義時にconstを使用しているために起きたエラー。
変更不可能(Unmodifiable)なリストに対してaddやremoveを実行しようとしていたために発生。

投稿2023/08/13 06:03

ituking

総合スコア80

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

エラーの通り、問題は以下の部分です。

widget.post.likedUserIds.add(widget.post.postAccountId);

Postクラスがどうなっているかわかりませんが、likedUserIdsは変更不可なListなため、追加/削除をするとこのエラーになります。
名前から想像するに、Postクラスはサーバーから取得した時点のある投稿の状態を表しているだけで、サーバーにあるPostに対する編集機能を持っていないので、likedUserIdsも変更できないようになっていると思われます。

一般的なSNSの実装だと、Likeの状態を切り替えるAPI(RESTなどのリクエスト)が別にあり、それを呼び出すと状態が変化した後のPostが返ってくる、というのがよくあるパターンだと思います。
まずはサーバー側に対してLikeの状態を切り替えるAPIの仕様を確認してみてください。

投稿2023/08/12 11:12

Shunly

総合スコア125

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問