大家好
事情是这样的,我正在做一个消息应用程序。首先,一条消息被写入Texfield
,然后通过按下按钮将消息保存在数据库中。
保存消息
var _mesajCont = TextEditingController();
...
onPressed: () async {
if (_mesajCont.text.trim().length > 0) {
Mesaj _kaydedilecMesaj = Mesaj(
bendenMi: true,
message: _mesajCont.text,
kimden: _chatModel.currentUser!.userID,
kime: _chatModel.sohbetedilenUser!.userID);
var sonuc = await _chatModel.saveMessage(_kaydedilecMesaj); <--- SAVE MESSAGE
if (sonuc) {
_mesajCont.clear();
}
}
},
数据库服务(此处保存消息并获取消息方法)
Future<bool> saveMessage(Mesaj kaydedilecMesaj) async {
var mesajID = _firestoreDB.collection("konusmalar").doc().id;
var _myDocID = kaydedilecMesaj.kimden + "--" + kaydedilecMesaj.kime;
var _alici = kaydedilecMesaj.kime + "--" + kaydedilecMesaj.kimden;
var _kaydedilecMap = kaydedilecMesaj
.toMap(); // bundan nesne üretince false sorunu düzeldi ilginc
await _firestoreDB
.collection("konusmalar")
.doc(_myDocID)
.collection("mesajlar")
.doc(mesajID)
.set(_kaydedilecMap);
await _firestoreDB.collection("konusmalar").doc(_myDocID).set({
"konusma_sahibi": kaydedilecMesaj.kimden,
"kimle_konusuyor": kaydedilecMesaj.kime,
"son_yollanan_mesaj": kaydedilecMesaj.message,
"konusma_goruldu": false,
"olusturulma_tarihi": FieldValue.serverTimestamp(),
});
_kaydedilecMap.update("bendenMi", (value) => false);
await _firestoreDB
.collection("konusmalar")
.doc(_alici)
.collection("mesajlar")
.doc(mesajID)
.set(_kaydedilecMap);
await _firestoreDB.collection("konusmalar").doc(_alici).set({
"konusma_sahibi": kaydedilecMesaj.kime,
"kimle_konusuyor": kaydedilecMesaj.kimden,
"son_yollanan_mesaj": kaydedilecMesaj.message,
"konusma_goruldu": false,
"olusturulma_tarihi": FieldValue.serverTimestamp(),
});
return true;
}
Stream<List<Mesaj>> getMassage(
String currentUserID, String sohbetEdilenUserID) {
var snapShot = _firestoreDB
.collection("konusmalar")
.doc(currentUserID + "--" + sohbetEdilenUserID)
.collection("mesajlar")
//.where("konusma_sahibi", isEqualTo: currentUserID)
.orderBy("date", descending: true /*tarihi son olanı öne koyar*/)
.limit(1)
.snapshots();
return snapShot.map((mesajListesi) =>
mesajListesi.docs.map((mesaj) => Mesaj.fromMap(mesaj.data())).toList());
}
之后,我使用Consumer
结构来侦听新消息。
Widget _buildMesajListesi() {
return Consumer<ChatViewModel>(builder: (context, value, child) {
return Expanded(
child: ListView.builder(
reverse: true,
controller: _scrollCont,
itemBuilder: ((context, index) {
return talkingBalloon(value.mesajlarListesi![index]); <--New talking baloon
}),
itemCount: value.dahaVarmii
? value.mesajlarListesi!.length + 1
: value.mesajlarListesi!.length,
),
);
});
}
然后,我创建了一个方法来监听打开页面时的新消息。
ChatViewModel.dart
List<Mesaj>? _tumMesajlar;
List<Mesaj>? get mesajlarListesi => _tumMesajlar;
.....
void yeniMesajListenerGet() {
_userRepository
.getMessage(currentUser!.userID, sohbetedilenUser!.userID)
.listen((anlikData) {
debugPrint("LISTENER GET DATA=>>>${anlikData[0].toString()}");
if (anlikData[0] != null) {
if (_listeyeilkMesaj!.date!.millisecondsSinceEpoch !=
anlikData[0].date!.millisecondsSinceEpoch) {
_tumMesajlar!.insert(0, anlikData[0]);
}
}
});
}
问题是,我发送了一次消息,一条消息在数据库中注册,但listen
工作了2次,控制台中的响应是:〉
LISTENER GET DATA=〉〉〉WHO XzAHsfvxmYUqHirg 5eH 7ifT 0 Qtf 1,TO WHO WoxT 4 Nxomeh 1 MQOE 6p 8 eOadgRYa 2,ME-〉true,MESSAGE相同的消息,但不同的时间戳,TİMESTAMP时间戳(秒=1679296897,纳秒=792506000)
LISTENER GET DATA=〉〉〉WHO XzAHsfvxmYUqHirg 5eH 7ifT 0 Qtf 1,TO WHO WoxT 4 Nxomeh 1 MQOE 6p 8 eOadgRYa 2,ME-〉true,MESSAGE相同的消息但不同timeStamp,TİMESTAMP Timestamp(seconds=1679296914,nanoseconds=30000000)〈--- database timestamp
不同日期(数据库成功映像here)
我试着分享了很多细节,这样就很容易理解了。如果你看到有什么遗漏,请让我知道。
1条答案
按热度按时间yacmzcpb1#
我在
Mesaj.fromMap
方法的date
部分添加了Timestamp .now()
,这样它就不会返回null。我删除了它,现在初始值返回null,在firebase被保存消息后,实际日期返回。我去掉了返回null的数据。控制台显示:
LISTENER GET DATA=〉〉〉MESSAGE hhjggrhhg,TİMESTAMP null
监听器获取数据=〉〉〉消息hhjggrhhg,TİMESTAMP时间戳(秒=1679379294,纳秒=812000000)
if
变化不大有什么想法吗?请分享。