【问题标题】:Firebase firestore WEB v.9 retrieve data ID-s from collection where that current user ID containsFirebase firestore WEB v.9 从当前用户 ID 包含的集合中检索数据 ID-s
【发布时间】:2021-10-21 10:58:22
【问题描述】:

我正在尝试从 firebase 检索特定数据,在我的 redux 商店中,我有 uniq id,我可以在这样的任何页面中获取它

const currentUser = useSelector(selectLoggedInUser); 
console.log(currentUser.id) // "71dc954d-d2a4-4892-8257-98696fe776cd" this is peace of doc name in "dms" collection

我想要所有包含这个ID的doc-s“71dc954d-d2a4-4892-8257-98696fe776cd”,我怎么查询呢??? 这就是我设置“dms”消息的方式

export const sentDirectMsg = async ({ toUid, currentUid, message, name }) => {
  const collecitonRef = await dmCollection(toUid, currentUid);
  await addDoc(collecitonRef, {
    timestamp: serverTimestamp(),
    message,
    name,
  });
};

const dmCollection = async (toUid, currentUid) => {
  const idPair = [currentUid, toUid].sort().join("_");
  return collection(db, "dms", idPair, "messages");
};

对此我不够清楚抱歉(只是没有足够的经验),我会尽力而为。 我正在尝试创建类似 Slack 的应用程序(我有很多页面和功能,我从一个地方导出到另一个地方),我将展示我如何实现从 firebase 发送和获取的频道消息,然后解释我如何制作直接消息

//Function that sent message to exact channelId /channels/someChannelId/messages
// channelId is literal with dynamic id
export const sentMsg = async ({ name, message, channelId }) => {
  await addDoc(collection(db, "channels", channelId, "messages"), {
    timestamp: serverTimestamp(),
    message,
    name,
  });
}; 
//Getting data from channel
      const messagesRef = query(
        collection(db, `channels/${channelId}/messages`),
        orderBy("timestamp")
      );
      onSnapshot(messagesRef, (snapshot) => {
        setMessages(snapshot.docs);
      }); 

现在我需要 DM,因为它需要一些隐私,所以我不能这样做,因为它需要一些隐私,只有 2 人应该看到这些消息,所以我需要 2 个具有 uniq id 并且他们的消息集合也是 uniq 的 uniq 人(所以只有他们才能看到彼此的消息),一般来说,当我在我的应用程序中注册用户时,我也会用他们保存 uniq ID,例如这个“71dc954d-d2a4-4892-8257-98696fe776cd”,

//This is how I sent direct messages
// toUid - to whom I should sent
// currentUid - is who is sent
const sentDirectMsg = async ({
  toUid,
  currentUid,
  message,
  name,
}) => {
  const collecitonRef = await dmCollection(toUid, currentUid);
  await addDoc(collecitonRef, {
    timestamp: serverTimestamp(),
    message,
    name,
  });
};

const dmCollection = async (toUid, currentUid) => {
  const idPair = [currentUid, toUid].sort().join("_");
  return collection(db, "dms", idPair, "messages");
}; 

// 当我从人发送消息的地方对这两个唯一 ID 进行排序时,它始终是相同的集合引用。 我的问题是我可以通过“查询”或“在哪里”获取所有包含当前用户 ID 的文档吗???

【问题讨论】:

  • 当您说包含此ID时,您希望该ID 存储在哪里?
  • 它已经存储在 firebase 中,如果您查看照片,最后一个文档的名称中具有相同的 ID。我只想要来自该文档的消息(包含当前用户 ID)
  • 可以添加消息集合数据结构吗?
  • 我当然可以从那里阅读消息
  • 如果不对您的数据结构有更多见解,我将无法提供太多帮助。您提到使用 id 已经是您的文档键,而它看起来像是一个复合键。您的文档 ID (user-id_XXX) 的第二个隔间是什么?

标签: reactjs firebase google-cloud-firestore where-clause


【解决方案1】:

已编辑:

如果我理解正确,你想得到一个文档,其中 id 包含你正在寻找的 id 的一部分。

使用array-contains 应该可以解决问题:

const dmsRef = collection(db,"dms"); 
const docRef = query(dmsRef, where("idPair", "array-contains", id)); //for example id = "71dc954d-d2a4-4892-8257-98696fe776cd"

const docSnap = await getDoc(docRef);

if (docSnap.exists()) {
  console.log("Document data:", docSnap.data());
} else {
  // doc.data() will be undefined in this case
  console.log("No such document!");
}

我的示例基于官方文档中的this link

【讨论】:

  • 在我的例子中,这个“71dc954d-d2a4-4892-8257-98696fe776cd”只是doc的一部分,doc的全名是这样的“71dc954d-d2a4-4892-8257-98696fe776cd_c51a0b24- bf1e-4b50-8deb-344476b97eb3" 我只想看看 doc 的 id 是否包含部分 (71dc954d-d2a4 ...)
  • 查看编辑后的答案是否对您有用
【解决方案2】:

如果您的数据模型以通过唯一 ID 识别用户为中心,那么您可以直接存储您的数据以反映他的模型:

const userData = {
  name: 'Marouane',
  state: 'BN',
  country: 'TUN'
};

// Add the user document in collection `dms`, with the id being the user ID
const res = await db.collection('dms').doc('71dc954d-d2a4-4892-8257-98696fe776cd').set(userData);

然后您可以使用其唯一标识符查询用户文档:

Firebase v8

const userRef = db.collection('dms').doc('71dc954d-d2a4-4892-8257-98696fe776cd');
const doc = await userRef();
if (!doc.exists) {
  console.log('No such user!');
} else {
  console.log('User dms data:', doc.data());
}

编辑(添加 firebase v9 - 模块化):

import { getFirestore, ref, onValue } from "firebase/firestore";

const db = getFirestore(firebaseApp);
const userRef = ref(db, 'dms/71dc954d-d2a4-4892-8257-98696fe776cd');
onValue(userRef, (snapshot) => {
  const data = snapshot.val();
  console.log(data);
});

如果事先不知道您的文档ID,您可以查询所有可用的文档并过滤掉与您的用户ID不匹配的文档:

import { getFirestore, collection, query, where, getDocs } from "firebase/firestore";

const db = getFirestore(firebaseApp);

const q = query(collection(db, "dms"));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
  if (doc.id.startsWith('71dc954d-d2a4-4892-8257-98696fe776cd')) {
    console.log(doc.data());
  }
});

同时,这种方法会导致性能大幅下降,最好通过重新设计存储。

【讨论】:

  • 你能告诉我它在 firebase 版本 9 中的样子吗,让我有点困惑。
  • 我添加了更新的 v9 方法以及基于用户 ID 的文档的动态 ID 标识。
猜你喜欢
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2019-05-03
  • 2016-12-11
相关资源
最近更新 更多