final FirebaseApp app = await FirebaseApp.configure(
name: 'test',
options: const FirebaseOptions(
googleAppID: '1:79601577497:ios:5f2bcc6ba8cecddd',
gcmSenderID: '79601577497',
apiKey: 'AIzaSyArgmRGfB5kiQT6CunAOmKRVKEsxKmy6YI-G72PVU',
projectID: 'flutter-firestore',
),
);
final Firestore firestore = Firestore(app: app);
runApp(MaterialApp(
title: 'Firestore Example', home: MyHomePage(firestore: firestore)));
}
@override
Widget build(BuildContext context) {
DMProfile dmProfile = Provider.of<DMProfile>(context);
PlayerProfile playerProfile = Provider.of<PlayerProfile>(context);
return StreamBuilder<List<Message>>(
stream: Firestore.instance
.collection('chats')
.document(widget.chatId)
.collection('messages')
.orderBy('timestamp', descending: true)
.limit(20)
.snapshots()
.map((list) =>
list.documents.map((doc) => Message.fromFirestore(doc)).toList()),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return LoadingPage();
}
List<Message> messageStream = snapshot.data;
if (messages.length == 0) {
messages = messageStream;
hasMore = !(messageStream.length < 20);
} else if (messages.first.timestamp != null &&
messageStream.first.timestamp != null) {
if (messageStream.first.timestamp
.compareTo(messages.first.timestamp) !=
0) {
print('Not equal');
messages.insert(0, messageStream.first);
}
}
return Expanded(
child: ListView.builder(
reverse: true,
padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
controller: listScrollController,
itemCount: messages.length,
itemBuilder: (context, index) {
final messageText = messages[index].message;
final messageSender = messages[index].senderId;
final currentUser =
widget.isPlayer ? playerProfile.userId : dmProfile.userId;
return MessageBubble(
imageUrl: messageSender == playerProfile.userId
? playerProfile.imageUrl
: dmProfile.imageUrl,
text: messageText,
isMe: currentUser == messageSender,
);
},
),
);
},
);
}
sendMessage({
String sender,
String receiver,
String message,
bool isPlayer,
String dmName,
String playerName,
String dmImage,
String playerImage,
}) async {
String sender1 = sender.compareTo(receiver) < 0 ? sender : receiver;
String sender2 = sender.compareTo(receiver) > 0 ? sender : receiver;
String chatName = '${sender1}_$sender2';
await Firestore.instance
.collection(CHAT_COLLECTION)
.document(chatName)
.setData({
'dm': isPlayer ? receiver : sender,
'dm_image': dmImage,
'dm_name': dmName,
'player': isPlayer ? sender : receiver,
'player_image': playerImage,
'player_name': playerName,
'dm_hidden': false,
'player_hidden': false,
'timestamp': FieldValue.serverTimestamp(),
'dm_seen': isPlayer ? false : true,
'player_seen': isPlayer ? true : false,
'last_message': {
'message': message,
'sender_name': isPlayer ? playerName : dmName,
'sender_id': sender,
'receiver_id': receiver,
},
}, merge: true);
await Firestore.instance
.collection(CHAT_COLLECTION)
.document(chatName)
.collection(MESSAGES_COLLECTION)
.add({
'sender_id': sender,
'receiver_id': receiver,
'sender_name': isPlayer ? playerName : dmName,
'message': message,
'timestamp': FieldValue.serverTimestamp(),
});
}
Ive尝试了所有的方法,尽可能多地查看文档,但似乎找不到解决方案。
vue3 中说 createApp 只能调用一次,可是我现在有两个场景需要手动挂载 组件的情况: 场景一 手动挂载弹窗,比如我手动挂载一个按钮组件: vue3 中不再支持 extend, 因此我使用createApp代替,可是第二次调用createApp的返回值和第一次调用的返回值不同,第二次的返回值没有umount方法,挂载后无法手动卸载应用。 场景二 有你一个表格,我使用render函数自定义
问题内容: 我有一个包含多个CTE的相当复杂的查询,但是其他人都从中提取了1个主要CTE,这是否会导致该主要CTE多次执行? 问题答案: 您可以这样使用CROSS JOIN: 这将防止的多次执行(有关实际执行计划,请参见属性)。 示例:如果执行此查询 使用数据库,那么实际的执行计划将是
我的主要活动是装载不同的碎片。此外,可以从MainActivity打开设置-activity。 如果用户只是在片段之间切换,那就万事大吉了。 当打开设置-activity并返回MainActivity时,onResume和onPause会被调用两次。如果用户打开设置-activity并再次返回MainActivity,onResume和onPause将被调用三次。每次用户打开“设置-activit
我试图为BillingClient v.2.2.0和Kotlin协同程序编写一个包装: 正如您所见,当我试图查询购买或购买时,我确保客户已经准备好。但在生产中存在许多错误: 我试图了解问题的原因,得到了if将被多次调用。可能存在异常。我一直想知道这是怎么可能的,因为我每次调用都会创建新的侦听器?我无法在emulator或测试设备上重现此问题。有人能解释一下这里发生了什么,以及如何解决吗?
问题内容: 我遇到了一个问题,我想绑定到ng-repeat循环内的函数的输出。我发现该函数每个项目被调用两次,而不是我期望的那样。这是ng- repeat部分(请注意最后的calcRowTotal()调用): calcRowTotal()函数如下所示: 接下来显示其中一个要迭代的项目的示例: 我在控制台中看到以下内容(我正在遍历的集合中当前有两项): 我当然可以做一个“ rowTotal”属性,但
我读在初始渲染时只被调用一次,但我看到它被渲染了多次。 似乎我创建了一个递归循环。 组件didMount调度动作来获取数据 一旦接收到数据,它就会触发成功操作,将数据存储在redux状态。 父反应组件连接到redux存储,并且具有mapStateToProps用于刚刚在上述步骤中更改的条目 父渲染子组件(通过变量编程选择) 子组件的组件didMount再次被调用 它消除了获取数据的操作 我想这就是