我正在设计一个使用java android与FireStore作为后端社交应用程序。一开始,Firestore建模可能是一个很大的变化,正如我所读到的,我试图保持文档小,不做太多的子集合,让我们假设以下场景:
一个用户可以创建几个配置文件
一个配置文件有兴趣
一个用户可以关注或取消关注许多配置文件,因此一个配置文件可以被很多用户关注
用户(集合)
uid: uidUserOne
name: jeff
概要(集合)
idProfile: idProfileOne
name: nameProfileOne
兴趣:{瑜伽:true,跑步:true,攀岩:true}
createdBy: uidUserOne
这里开始我的疑问,不确定如何建模的关注/取消关注功能,我有三个选项在脑海中:
<标题>选择创建一个集合,其中每个文档映射一个遵循一个配置文件关系的单个用户follower (collection)
uid: uidUserOne
idProfile: idProfileOne
选项B
一个文档映射每个概要文件的追随者,我将概要文件后面的用户uid保存在一个数组中。
追随者(集合)
idProfile: idProfileOne
followers: {uidUserOne: true, uidUserTwo: true,…}
选项C
一个文档映射每个用户的以下内容,我将用户后面的配置文件id保存在数组
中追随者(集合)
uid: uidUserOne
如下:{idProfileOne: true, idProfileTwo: true,…}
我想知道哪个选项是最好的,A, B或C,如果它可以是一个更好的…可能
我还有另一个疑问,我该如何做以下查询:
假设我是用户1,我已经关注了两个对瑜伽感兴趣的配置文件,所以我想列出我还没有关注的对瑜伽感兴趣的配置文件,不知道如何完成这个。
据我所知,你的回答提供了一个与实时数据库相关的以下系统的解决方案,而你的问题与Firestore相关。请注意,这两个数据库都是Firebase的一部分,但它们是两个不同的产品,具有两种不同的机制。
并回答你的问题:
选项a .创建一个集合,其中每个文档映射一个遵循一个配置文件关系的单个用户
即使这个解决方案听起来有点昂贵,因为Firestore中的所有内容都与阅读数量有关,但对于拥有合理数量的用户/关注者的应用程序来说,这可能是一个值得考虑的解决方案。几年前我曾回答过一个类似的问题,所以请查看下面我的答案:
- Firestore -如何构建feed和跟踪系统
但是,想象一下阅读一个拥有100万关注者的用户的成本是多少?
选项B.一个文档映射每个配置文件的追随者,我将跟随该配置文件的用户uid保存在一个数组中。
这也是一个可以继续使用的解决方案。但也要记住,文档是有限制的,所以恐怕一个文档不能容纳100万个uid。但是,您可以创建一个新的每次达到限制时都要记录。我已经创建了一个库,可以帮助您根据1 MiB的最大大小检查文档大小:
- https://github.com/alexmamo/FirestoreDocument-Android/tree/master/firestore-document
选项c一个文档映射每个用户的以下内容,我将用户后面的配置文件id保存在数组
中
该选项与选项b相同。
假设我是用户1,我已经关注了两个对瑜伽感兴趣的配置文件,所以我想列出我还没有关注的对瑜伽感兴趣的配置文件,不知道如何完成这个。
在本例中,"集合"解决方案是一个可以继续使用的解决方案,因为您可以将兴趣数组添加到跟踪用户的每个UID文档中。
编辑:
让我们假设你有兴趣关注那些对瑜伽感兴趣而你不关注的用户。下面是一个可以帮助您实现这一目标的模式:
Firestore-root
|
--- users (collection)
| |
| --- $uid (document)
| |
| --- interests: ["yoga", "running", "climbing"]
|
--- followers
|
--- $uid (document)
|
--- userFollowers (sub-collection)
|
--- $followerUid (document)
|
--- //Data
要得到想要的结果,需要两个查询。一种是获得对瑜伽感兴趣的用户,另一种是只获得你不关注的用户。实际上,您需要检查userfollower子集合中没有出现哪个用户。要检查用户是否不存在,请使用以下代码行:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
DocumentReference followerUidRef = rootRef
.collection("followers").document(uid)
.collection("userFollowers").document(followerUid);
followerUidRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (!document.exists()) {
//Follow the user
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});