javascript - Firebase 和 Algolia 确保搜索没有搜索命中

标签 javascript node.js firebase algolia

我在使用 Firebase 和 Algolia 实现安全搜索时遇到了一些问题。
我一直在关注 https://firebase.google.com/docs/firestore/solutions/search 上的指南-> 添加安全性
我的问题是一切似乎都运行良好,但是我没有收到任何搜索命中。
当用户搜索一个项目时,它会调用一个函数,该函数首先命中一个 firebase 函数以生成一个安全 API key ,该 key 还包括查询的安全过滤器。
火力基地功能:

app.use(getFirebaseUser);

app.get('/', (req, res) => {
  // @ts-ignore
  const uid = req.user.uid;

  // Create the params object as described in the Algolia documentation:
  // https://www.algolia.com/doc/guides/security/api-keys/#generating-api-keys
  const params = {
    // This filter ensures that only documents where author == uid will be readable
    filters: `ownerID:${uid}`,
    // We also proxy the uid as a unique token for this key.
    userToken: uid,
  };

  // Call the Algolia API to generate a unique key based on our search key
  const key = client.generateSecuredApiKey(ALGOLIA_SEARCH_KEY, params);

  // Then return this key as {key: '...key'}
  res.json({key});
});

这实际上是从 firebase 示例中复制/粘贴的,除了我用“ownerID”替换了“author”,这是我想在我的索引中匹配的术语。
getFirebaseUser() 是官方 firebase 示例的精确复制/粘贴。
一旦客户端收到安全的 API key ,它就会通过查询传递给 algolia:
const getSearchResults = async (query: string) => {
  const index = client.initIndex('things');
  try {
    const userToken = await auth.currentUser?.getIdToken();
    const response = await fetch(GOOGLE_URL, {
      headers: { Authorization: `Bearer ${userToken}` },
    });
    const data = await response.json();
    const client = algoliasearch(ALGOLIA_APP_ID, data.key);
    const responses = await index.search(query);
    console.log(responses);
  } catch (err) {
    console.error(err.message);
  }
};
这也是与示例相同的功能,不同之处在于使用 async/await 编写。 (我确实尝试了精确的复制/粘贴,结果是一样的)。
此外,该示例显示了 index.search({query}) ,其中查询字符串作为对象传入。这也不起作用,并且 Typescript 声明需要一个字符串。
如果我尝试将 initIndex 更改为不存在的索引,则会收到一条错误消息,指出它不存在。这告诉我我的应用程序和 algolia 之间的连接按预期工作。
返回的对象如下所示:
exhaustiveNbHits: true
hits: []
hitsPerPage: 20
nbHits: 0
nbPages: 0
page: 0
params: "query=test&filters=ownerID%3AKK3oXEkrIKb31BECDSJPMdgvTBz2&userToken=KK3oXEkrIKb31BECDSJPMdgvTBz2"
processingTimeMS: 1
query: "test"
如果我进行常规搜索:
const getSearchResults = async (query: string) => {
  const client = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_SEARCH_API_KEY);
  const index = client.initIndex('things');

  const responses = await index.search(query);
  console.log(responses);
};
我确实得到了点击:
exhaustiveNbHits: true
hits: Array(1)
0: {productName: "test ja", purchaseDate: "15.03.2021", purchasedFrom: "ok", ownerID: "KK3oXEkrIKb31BECDSJPMdgvTBz2", objectID: "25BadjQxUjRjkjH9ZnwW", …}
length: 1
__proto__: Array(0)
hitsPerPage: 20
nbHits: 1
nbPages: 1
page: 0
params: "query=test"
processingTimeMS: 1
query: "test"
这实际上是绕过了整个云功能,这意味着问题必须与生成安全 API key 、参数或其他东西有关。
Algolia 中存储的索引数据如下所示:
objectID "25BadjQxUjRjkjH9ZnwW"

productName "test ja"

purchaseDate "15.03.2021"

purchasedFrom "ok"

ownerID "KK3oXEkrIKb31BECDSJPMdgvTBz2"
这意味着我应该点击我在云功能中拥有的 ownerID。

编辑:
将参数对象的过滤器设置为空字符串时,我收到搜索命中。过滤器的实现方式可能有问题。

感谢您查看这个。我将不胜感激我能得到的所有帮助!
斯蒂芬·瓦卢瓦

最佳答案

我与 algolia 取得了联系,并找出了问题所在。
代码或搜索的设置方式没有任何问题。
文档中没有提到的一件事是我匹配的属性 (ownerID) 没有被声明为分面的属性。
通过转到 Algolia 应用程序中的 Configuration -> Facets,并在那里添加对象键,一切都按预期工作。 (将其视为“不可搜索”)。该属性不应该是可搜索的。它只能用于将索引与正确的用户匹配。
如果有人使用 Algolia 进行安全搜索,无论您使用的是 Firebase 函数还是其他后端,都必须在 Facets 中设置过滤器中的属性。

关于javascript - Firebase 和 Algolia 确保搜索没有搜索命中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66669255/

相关文章:

node.js - MongoDB 连接字符串是否需要 ReplicaSet 中每个服务器的身份验证详细信息?

javascript - momentjs 返回一个对象

javascript - 从 View 调用函数后尝试将数据数组设置为 $scope

javascript - Promise 将文件写入文件系统

node.js - 服务员不发出现场事件

node.js - node-postgres:缓存的参数化插入查询,第二次运行失败

javascript - 如何在 React Native 中将 Firebase 实时数据库数据值增加一个?

swift - 如何在 Swift 中按数组计数对 Firebase NSDictionary 项进行分组?

javascript - 防止用户独立于 addPost 调用 Firebase 中的incrementPostCount函数

javascript - 我有一组字符串数据,我希望将其绘制在所需的分区中,并将字符串整齐地靠近绘制的圆圈