Flutter:Firebase Realtime从对象列表中删除对象

Dom*_*oMG 5 dart firebase firebase-realtime-database flutter

我正在咨询数据库中注册的所有俱乐部。对于每个俱乐部,我都将其添加到对象列表中。

当该人删除俱乐部时,将从数据库中删除俱乐部,但是在项目列表中没有删除,我尝试执行以下操作:

我的NotClub-Player.dart类

// FIREBASE CLUBS
List<Club> items = List();
Club item;
DatabaseReference itemRef;

@override
void initState() {
   super.initState();
   item = Club("","","",0,"","","","",0,0,false,"","","","","",false,"","","","","","","","","","","");
   final FirebaseDatabase database = FirebaseDatabase.instance;
   itemRef = database.reference().child(player.player_game_platform).child("CLUB");
   itemRef.onChildAdded.listen(_onEntryAdded);
   itemRef.onChildRemoved.listen(_onEntryRemoved);
   itemRef.onChildChanged.listen(_onEntryChanged);
}

// CLUBS LISTENERS
_onEntryAdded(Event event) {
 setState(() {
   items.add(Club.fromSnapshot(event.snapshot));
 });
}

_onEntryRemoved(Event event) {
 setState(() {
   items.remove(Club.fromSnapshot(event.snapshot));
 });
}

_onEntryChanged(Event event) {
 var old = items.singleWhere((entry) {
   return entry.key == event.snapshot.key;
 });
 setState(() {
   items[items.indexOf(old)] = Club.fromSnapshot(event.snapshot);
 });
}
Run Code Online (Sandbox Code Playgroud)

我的问题:_onEntryRemoved中有一个事件。在这种情况下,它将返回已删除的项目。但是它不会从列表中删除相应的项目。

在数据库中,已成功将其删除。但是包含对象的列表尚未删除它。

这是我的查询

rnew Flexible(
            child: new FirebaseAnimatedList(
              query: FirebaseDatabase.instance.reference().child(player.player_game_platform).child("CLUB").orderByChild("club_name"),
              itemBuilder: (BuildContext context, DataSnapshot snapshot,
                  Animation<double> animation, int index) {
                return new Column(
                  children: <Widget>[
                    new Container(
                      decoration: new BoxDecoration(
                        color: Colors.grey[300],
                      ),
                      child: new ListTile(
                        leading: new CachedNetworkImage(imageUrl: items[index].club_logo, width: 60.0),
                        title: new Text(items[index].club_name, style: new TextStyle(color: Colors.black)),
                        subtitle: new Text("CAPTAIN: "+items[index].club_captain, style: new TextStyle(color: Colors.black)),
                        trailing: new RaisedButton(
                            color: Colors.lightBlue[500],
                            child: new Text("JOIN", style: new TextStyle(color: Colors.white)),
                            onPressed: (){

                            }
                        ),
                      ),
                    ),
                    new Divider(
                      color: Colors.grey[700],
                      height: 0.0,
                    ),
                  ],
                );
              },
            ),
          ),
Run Code Online (Sandbox Code Playgroud)

在这里,我从_onEntryRemoved中获得了什么 -它返回正确的删除,但是删除列表不适用于我。

E/flutter (15214): [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
E/flutter (15214): setState() called after dispose(): _join_clubState#a99f1(lifecycle state: defunct, not mounted)
E/flutter (15214): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback. The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
E/flutter (15214): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
E/flutter (15214): #0      State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1098:9)
E/flutter (15214): #1      State.setState (package:flutter/src/widgets/framework.dart:1124:6)
E/flutter (15214): #2      _join_clubState._onEntryRemoved (package:proclubscommunity/Club-Player.dart:807:5)
E/flutter (15214): #3      _RootZone.runUnaryGuarded (dart:async/zone.dart:1316:10)
E/flutter (15214): #4      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:330:11)
E/flutter (15214): #5      _DelayedData.perform (dart:async/stream_impl.dart:578:14)
E/flutter (15214): #6      _StreamImplEvents.handleNext (dart:async/stream_impl.dart:694:11)
E/flutter (15214): #7      _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:654:7)
E/flutter (15214): #8      _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/flutter (15214): #9      _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
I/flutter (15214): {club_logo: url_image, club_note: , club_since: , club_three_position: , club_market: false, club_market_color: , club_six_position: , club_premium: false, club_twitter: https://www.twitter.com/, club_first_position: , club_category: 0, club_seven_position: , club_description: , club_copa: 0, club_country: ESPAÑA, club_liga: 0, club_four_position: , club_logo_file_name: club_logo.png, club_plataform: PS4, club_nine_position: , club_captain: RaiiLKilleR, club_name: Barcelona, club_five_position: , club_eight_position: , club_id: 1, club_second_position: , club_logo_folder_name: PS4_Barcelona, club_twitch: https://www.twitch.tv/, club_youtube: https://www.youtube.com/}
Run Code Online (Sandbox Code Playgroud)

向小部件添加密钥:

            return new Column(
              key: new ObjectKey(items[index].club_name),
              children: <Widget>[
                new Container(
                  decoration: new BoxDecoration(
                    color: Colors.grey[300],
                  ),
                  child: new ListTile(
                    leading: new CachedNetworkImage(imageUrl: items[index].club_logo, width: 60.0),
                    title: new Text(items[index].club_name, style: new TextStyle(color: Colors.black)),
                    subtitle: new Text("Captain: "+items[index].club_captain, style: new TextStyle(color: Colors.black)),
                    trailing: new RaisedButton(
                        color: Colors.lightBlue[500],
                        child: new Text("JOIN", style: new TextStyle(color: Colors.white)),
                        onPressed: (){

                        }
                    ),
                  ),
                ),
                new Divider(
                  color: Colors.grey[700],
                  height: 0.0,
                ),
              ],
            );
Run Code Online (Sandbox Code Playgroud)

_onEntryRemoved()

  _onEntryRemoved(Event event) {
    setState(() {
      print(event.snapshot.value['club_name']);
      items.remove(event.snapshot.value['club_name']);
    });
  }
Run Code Online (Sandbox Code Playgroud)

Feu*_*Feu 2

你的问题出在Club.

当您创建List<Club> items并稍后执行时items.remove(clubInstance),该remove方法在内部将使用标准对象 equals 方法实现,该实现不知道您的密钥。

如果您尝试使用,也会发生同样的情况items.indexOf(clubInstance)。它永远不会“找到”该项目,总是返回-1

您可以更改您的实现,迭代项目以准确找出您需要删除的项目,然后将其删除,或者您可以在 Club 类中实现==和。hashCode

如果您打算用作club_name密钥,添加这两行可能会解决它。

class Club {
  Club({this.club_name});
  final String club_name;

  // this is what you would have to add to your class:
  bool operator ==(o) => o is Club && o.club_name == club_name;
  int get hashCode => club_name.hashCode;
}
Run Code Online (Sandbox Code Playgroud)

注意:这与 flutter 或 firebase 无关,这只是 dart!