Flutter:Firebase Realtime从对象列表中删除对象 [英] Flutter: Firebase Realtime Remove object from a list of objects

查看:123
本文介绍了Flutter:Firebase Realtime从对象列表中删除对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



我的NotClub-Player.dart类

  // FIREBASE CLUBS 
List< Club>项目= List();
俱乐部物品;
DatabaseReference itemRef;

@override
void initState(){
super.initState();
item = Club(,,,0,,,,,0,0,false,,,,, ,假,,,,,,,,,,,);
最终的FirebaseDatabase数据库= FirebaseDatabase.instance;
itemRef = database.reference()。child(player.player_game_platform).child( CLUB);
itemRef.onChildAdded.listen(_onEntryAdded);
itemRef.onChildRemoved.listen(_onEntryRemoved);
itemRef.onChildChanged.listen(_onEntryChanged);
}

//俱乐部监听器
_onEntryAdded(Event event){
setState((){
items.add(Club.fromSnapshot(event。快照));
});
}

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

_onEntryChanged(事件事件){
var old = items.singleWhere((entry){
return entry.key == event.snapshot.key;
});
setState((){
items [items.indexOf(old)] = Club.fromSnapshot(event.snapshot);
});
}

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



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



这是我的查询

  rnew Flexible(
子级:new FirebaseAnimatedList(
查询:FirebaseDatabase.instance.reference()。child(player.player_game_platform).child( CLUB) .orderByChild( club_name),
itemBuilder:(BuildContext上下文,DataSnapshot快照,
Animation< double>动画,int索引){
return new Column(
children:< ; Widget> [
新Container(
装饰:new BoxDecoration(
颜色:Colors.grey [300],
),
子对象:new ListTile(
开头:new CachedNetworkImage(imageUrl:items [index] .club_logo,宽度:60.0),
标题:new Text(items [index] .club_name,样式:new Text样式(颜色:Colors.black)),
字幕:新文本( CAPTAIN: + items [index] .club_captain,样式:新文本样式(颜色:Colors.black)),
结尾: new RaisedButton(
颜色:Colors.lightBlue [500],
子级:new Text( JOIN,样式:new TextStyle(color:Colors.white)),
onPressed:() {

}
),
),
),
新的分隔线(
颜色:Colors.grey [700],
高:0.0,
),
],
);
},
),
),

在这里,我从_onEntryRemoved 中得到的信息-bbb-它返回正确的删除结果,但是删除列表不适用于我。

  E / flutter(15214):[错误:topaz / lib / tonic / logging / dart_error.cc(16)]未处理的异常:
E / flutter(15214):setState() dispose():_join_clubState#a99f1(生命周期状态:已关闭,未安装)
E / flutter(15214):如果在State对象上调用setState()导致不再出现在小部件中的小部件,则会发生此错误树(例如,其父窗口小部件不再在其构建中包括该窗口小部件)。当代码从计时器或动画回调中调用setState()时,可能会发生此错误。首选解决方案是取消计时器或停止收听dispose()回调中的动画。另一个解决方案是在调用setState()之前检查此对象的 mount属性,以确保该对象仍在树中。
E / flutter(15214):如果正在调用setState(),则此错误可能表示内存泄漏,因为在从树中删除该State对象后,另一个对象仍保留对该State对象的引用。为避免内存泄漏,请考虑在dispose()期间中断对此对象的引用。
E / flutter(15214):#0 State.setState。<匿名闭包> (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。 (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:否,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:巴塞罗那,club_five_position:,club_eight_position:,club_id:1,club_second_position:,club_logo_folder_name:PS4_Barcelona,club_twitch:https://www.twitch.tv, https://www.youtube.com/}

向小部件添加密钥:

 返回新列(
键:new ObjectKey(items [index] .club_name),
个子级:< Widget> ; [
新Container(
装饰:new BoxDecoration(
颜色:Colors.grey [300],
),
子对象:new ListTile(
领先:新的CachedNetworkImage(imageUrl:项目[index] .club_logo,宽度:60.0),
标题:新的Text(项目[index] .club_name,样式:新的TextStyle(color:Colors.black)),
副标题:new Text(队长: + items [index] .club_captain,样式:new TextStyle(颜色:Colors.black)),
尾随:new RaisedButton(
颜色:Colors.lightBlue [500],
子级:new Text( JOIN,样式:new TextStyle(color:Colors.white)),
onPressed:(){

}
),
),
),
新分隔线(
颜色:Colors.grey [700],
高度:0.0,
),
],
);

_onEntryRemoved()

  _onEntryRemoved(事件事件){
setState((){
print(event.snapshot.value ['club_name']);
items.remove(event.snapshot.value ['club_name']);
});
}


解决方案

您的问题出在俱乐部



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



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



您可以更改实现,反复进行通过这些项目来找出需要删除的项目,然后将其删除,或者可以实现 == hashCode

如果您打算使用 club_name 作为键,请添加这两行

  class Club {
Club({this.club_name});可能会解决。
final String club_name;

//这就是您必须添加到类中的内容:
bool运算符==(o)=> o是Club&& o.club_name == club_name;
int获取hashCode => club_name.hashCode;
}

注意:这与颤振或火力无关,这只是飞镖! / p>

I am consulting all the clubs registered in the database. And for every club I add it to a list of objects.

When the person deletes the club deletes the club from the database, but in the list of items is not deleted, I have tried to do the following:

My NotClub-Player.dart class

// 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);
 });
}

My problem: In _onEntryRemoved there is an event. In that event, it returns the item that has been deleted. But it does not delete the corresponding item from the list.

In the database, it has been successfully deleted. But the list containing the object has not deleted it.

This is my query

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,
                    ),
                  ],
                );
              },
            ),
          ),

Here what I get in the _onEntryRemoved - It returns the correct removal, But removing the list does not apply to me.

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/}

Adding key to the widget:

            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,
                ),
              ],
            );

_onEntryRemoved()

  _onEntryRemoved(Event event) {
    setState(() {
      print(event.snapshot.value['club_name']);
      items.remove(event.snapshot.value['club_name']);
    });
  }

解决方案

Your problem lies on Club.

When you create List<Club> items and later perform items.remove(clubInstance), internally the remove method will use the standard object equals method implementation, which is unaware of your key.

The same would happen if you try to use items.indexOf(clubInstance). It will never 'find' the item, always returning -1.

You can either change your implementation, iterating through the items to find out exactly which item you need to delete, and then remove it, OR you could implement == and hashCode in the Club class.

If you intend to use club_name as the key, adding these two lines will probably solve it.

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;
}

Note: this is unrelated to flutter or firebase, this is just dart!

这篇关于Flutter:Firebase Realtime从对象列表中删除对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆