- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
您好,我是一名自学 Flutter 的开发人员,正在编写我的第一个应用程序。我正在 Flutter 中构建一个基本的报价应用程序,它使用 Firebase 进行身份验证,使用 FireStore 作为数据库。这是 FireStore noSQL 架构:
有一个故事集合,它是只读数据,提供图像链接和文本,如下所示。请注意,文档 ID 是在故事集合中自动生成的:
然后是一个 Users 集合,用于存储用户数据,例如用户名、电子邮件、帐户创建日期时间和喜欢数组 [可能存储喜欢的故事]。在此集合中,文档的 ID 是经过身份验证(登录)的用户的 UID(唯一 ID)。
下面是我正在追寻的用户故事以及我的方法:
每当用户点击下面最喜欢的图标时,必须将赞保存到用户集合中,其中用户的 uid 是文档 ID,并将喜欢的故事存储在 likes 数组中。
Simulator Screenshot of UI before like
然后使用 if 语句说,如果经过身份验证的用户在 likes 数组中有故事,则将轮廓上的白色心形变成红色心形,如下所示:
Simulator Screenshot of UI after like
但是,我的代码中存在一个错误,当用户点击最喜欢的图标时,所有故事的红心都会立即变红。有人可以帮忙吗?这是代码片段:
class FirestoreSlideshowState extends State<FirestoreSlideshow> {
static const likedKey = 'liked_key';
bool liked;
final PageController ctrl = PageController(viewportFraction: 0.8);
final Firestore db = Firestore.instance;
Stream slides;
String activeTag = 'favs';
// Keep track of current page to avoid unnecessary renders
int currentPage = 0;
@override
void initState() {
super.initState();
_restorePersistedPreference();
_queryDb();
// Set state when page changes
ctrl.addListener(() {
int next = ctrl.page.round();
if (currentPage != next) {
setState(() {
currentPage = next;
});
}
});
}
void _restorePersistedPreference() async {
var preferences = await SharedPreferences.getInstance();
var liked = preferences.getBool(likedKey) ?? false;
setState(() {
this.liked = liked;
});
}
void _persistPreference() async {
setState(() {
liked = !liked;
});
var preferences = await SharedPreferences.getInstance();
preferences.setBool(likedKey, liked);
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: slides,
initialData: [],
builder: (context, AsyncSnapshot snap) {
List slideList = snap.data.toList();
return PageView.builder(
controller: ctrl,
itemCount: slideList.length,
itemBuilder: (context, int currentIdx) {
if (slideList.length >= currentIdx) {
// Active page
bool active = currentIdx == currentPage;
return _buildStoryPage(slideList[currentIdx], active);
}
});
});
}
Stream _queryDb({String tag = 'favs'}) {
// Make a Query
Query query = db.collection('Stories').where('tags', arrayContains: tag);
// Map the documents to the data payload
slides =
query.snapshots().map((list) => list.documents.map((doc) => doc.data));
// Update the active tag
setState(() {
activeTag = tag;
});
}
_buildStoryPage(Map data, bool active) {
final _width = MediaQuery.of(context).size.width;
final _height = MediaQuery.of(context).size.height;
// Animated Properties
final double blur = active ? 20 : 0;
final double offset = active ? 20 : 0;
final double top = active ? 75 : 150;
return AnimatedContainer(
duration: Duration(milliseconds: 500),
curve: Curves.easeOutQuint,
width: _width / 2,
height: _height,
margin: EdgeInsets.only(top: top, bottom: 20, right: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(data['img']),
),
boxShadow: [
BoxShadow(
color: Colors.black87,
blurRadius: blur,
offset: Offset(offset, offset))
]),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Text(data['quote'],
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontFamily: "Typewriter")),
),
),
SizedBox(height: 20),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(data['author'],
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontFamily: "Typewriter")),
),
SizedBox(height: 20),
Row(mainAxisAlignment: MainAxisAlignment.end, children: [
IconButton(
icon: Icon(liked ? Icons.favorite : Icons.favorite_border,
color: liked ? Colors.red : Colors.grey[50]),
onPressed: (){
_persistPreference();
} ),
IconButton(
icon: Icon(
Icons.share,
color: Colors.white,
),
onPressed: () {
share();
})
])
],
));
}
}
最佳答案
我建议为喜欢的人制作另一个收藏。如果此应用程序要扩展,由于 Firestore 文档的大小限制为 1 MB,您将限制用户的报价数量。所以这是一个建议的解决方案:
/likes/{likeId}
的文档结构
{
'userId': string
'quoteId': string
}
然后,如果您想加载喜欢的名言列表,您可以执行如下查询:
_db.collection(likes).where('userId', isEqualTo: currentUserId).get()
然后您可以从那里根据上面的结构从 likes 对象中包含的引用 ID 加载引用。为避免无故加载大量文档,您还可以实现 pagination在您的查询中。
所以现在当有人想要引用时,您可以在 likes 集合中创建一个新的 like 对象,其中包含引用 ID 和用户 ID,如上所示。
要删除/取消点赞,您需要找到同时匹配 userId 和 quoteId 的文档才能将其删除
var snap = _db.collection(likes).where('userId', isEqualTo: currentUserId).where('quoteId', isEqualTo: quoteId).get();
if(snap.docs != null && snap.docs.isNotEmpty){
//the record exists
snap.docs.first.ref.delete() // this will delete the first record in the database that matches this like. Ideally there will only ever be one (you should check to make sure a document doesn't already exist before creating a new one)
}
在 flutter 方面,您可能会有一个显示这些列表的 ListView。我建议制作一个组件,使用 future builder 从 id 加载报价。
如果您需要更多 Flutter 端代码示例,请告诉我。祝你好运!
关于firebase - 如何映射用户特定的喜欢/收藏夹?类似于大多数社交应用程序上的点赞功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65732310/
是否有一种 STL 算法允许我将一个函数应用于一个范围内的每个元素,转换元素,并将之前转换的元素作为输入? 我在想这样的事情(显然行不通,因为第二个迭代器将无效): struct Input {
我有一个字典列表,例如: l =[{country:'Italy',sales:100,cost:50}{country:'Italy',sales:130,cost:60} {co
考虑以下几点: $var = 'Now is the time' if ($var -like 'Now*') { 'true' } else { 'false' } 输出:真 现在交换 -like
我认为这是一个简单的问题,但尚未得到解决方案。我只想从此处解释的列中获取有效数字。 假设我们有一个包含以下值的 varchar 列 ABC Italy Apple 234.62 2:234:43:22
这个问题已经有答案了: MySQL LIKE IN()? (12 个回答) 已关闭 4 年前。 是否可以使用 IN 子句扩展 LIKE 表达式? 此时我得到以下 SQL: select * from
这个问题在这里已经有了答案: How to postpone/defer the evaluation of f-strings? (14 个答案) 关闭 3 年前。 考虑字符串 string_0
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 8 年前。 Improve t
我刚刚阅读了以下关于同一主题的帖子: Facebook like notifications tracking (DB Design)和 Database design to store notifi
我如何在 javascript 中创建一个新事件/像在 c# 中一样? private event EventHandler asdCompleted; private void SetEventHa
我经常访问一个名为 GOOD 的网站我特别喜欢一种审美风格;导航栏如何在网站背景中扩展其颜色。如果您访问该网站,就会明白我的意思。 在 CSS 中,我怎样才能以最简单的方式复制它?我已经用 z-ind
我对 LINQ 比较陌生,不知道如何执行 Like 条件。我有一个 myObject 的 IEnumerable 列表,想要做一些类似 myObject.Description 的事情,比如“Help
我正在尝试在 Sharepoint 2013 提供商托管的应用程序中构建一个类似人员选择器的工具。最初,我使用的是 Utility.ResolvePrincipal,它让我可以访问 Sharepoin
过去几个月我一直在研究微服务架构应用程序,我仍在努力适应分布式特性。我多次注意到一种模式,但我不确定处理它的首选方式是什么。 假设我们有服务 A、服务 B 和服务 C。服务 A 公开了一个 API,其
这个问题在这里已经有了答案: Equivalent to unix "less" command within R console (5 个回答) 6年前关闭。 R 控制台中是否有任何命令与 Linu
是否可以在 Xcode 中为类似于 emacs 中的“标记”功能的行添加书签?还有我可以用来跳转到行号的快捷方式吗?我的源代码变得很长且难以导航。 最佳答案 是的;如果您将文本插入符号放在要添加书签的
在使用 vi 15 年的大部分时间后,我在使用 Go 时一时兴起尝试了 Rob Pike 的 Acme。我真的很喜欢它的小巧轻便。现代 unix 风格的东西在 Acme 中表现不佳,而 Ruby 开发
我正在寻找可以打印矩阵[1:5, 1:5] 的任何包中的函数。 head() 适用于列数较少但矩阵较大的用户。我知道我可以为它创建自己的函数,但我想知道是否已经有函数了。 最佳答案 在名为futile
我正在用 C++ 构建一个聚类算法,但我不能很好地处理 OOP 和发生变化的变量(成员数据)的状态。对于某种复杂的算法,我发现这是我发展的障碍。 因此,我正在考虑将编程语言更改为一种功能语言:Ocam
我有一个这样的日志: Jun 21 06:25:07 172.25.1.1 kernel: DROP IN=ppp0 OUT= MAC= SRC=206.221.177.2 DST=185.79.95
我需要一些帮助来制作类似于 Accordion 的东西。目标是,如果您单击导航中的链接,一个部分会消失,而您单击的部分会出现(在相同位置且不明显)。 如果可能,它还应该自动滚动到该部分的开头(导航的结
我是一名优秀的程序员,十分优秀!