EXPO和Firebase实时数据库-在写入数据库之前读取值并确认不存在特定值

人气:677 发布:2022-10-16 标签: javascript firebase firebase-realtime-database react-native expo

问题描述

我有一个功能正常的Reaction Native EXPO应用程序,它与我的Firebase实时数据库交互。简而言之,我在试图找到一种方法来检查所有子值以查看是否存在某个值,然后将该值(再次)作为新记录写入数据库,这让我感到困惑。

我过去一直从我的App.js中的世博会推送通知API获取&Quot;ExponentPushToken&Quot;,然后在从世博会推送通知API注册推送通知的相同函数中使用以下代码立即向我的Firebase实时数据库写入新记录:

      const token = (await Notifications.getExpoPushTokenAsync()).data;
      console.log(token);
      var userListRef = firebase.database().ref("users/push_token");
      var newUserRef = userListRef.push();
      newUserRef.set(token);

我还有以下代码读取数据库并将正确的信息记录到控制台,以便能够将所有输出值与前面提到的";内标识&Quot;值进行比较:

var userListRef = firebase.database().ref("users/push_token");
  userListRef.on("value", function (snapshot) {
    snapshot.forEach(function (child) {
      console.log(child.val());
    });
  });
在I[2-0]和.set()在我的Firebase实时数据库中创建新记录之前,我试图获取";令牌并确认它不是我的Firebase Realtime数据库中的".val()";(跨数据库的现有值)。我也希望能够登录控制台进行验证。下面的代码不起作用...我在这里的尝试是尝试.push()到一个数组,并查看";标记&是否在数组中的某个位置。这种情况正在发生,但我使用";if/Else";语句的最后一个函数仍在为数据库中的每条记录循环。不确定如何在不为数据库中的每条记录循环后续函数的情况下编写此代码。

      const token = (await Notifications.getExpoPushTokenAsync()).data;
      console.log(token);
      var userListRef = firebase.database().ref("users/push_token");
      userListRef.once("value", function (snapshot) {
        snapshot.forEach(function (child) {
          createPushTokenArray(child.val());
          myTokenHandler(token);
        });
      });

  var allPushTokens = [];
  async function createPushTokenArray(dbState) {
    allPushTokens.push(dbState);
    return;
  }

  async function myTokenHandler(myToken) {
    await createPushTokenArray();
    var checkForValue = allPushTokens.includes(myToken);
    if (checkForValue === true) {
      return console.log("Push Token already stored in database.");
    } else {
      var userListRef = firebase.database().ref("users/push_token");
      var newUserRef = userListRef.push();
      var writeNewToken = newUserRef.set(myToken);
      writeNewToken;
      return console.log("New Push Token stored in database.");
    }
  }

我多次尝试在这一切中取得任何进展,但都是徒劳的。作为参考,下面是db结构(JSON格式):

{
  "users" : {
    "push_token" : {
      "key or name" : "value",
      "-Maer1EuNpR24LdhxmIl" : "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
    }
  }
}

推荐答案

实际上我自己就能弄清楚,对任何感兴趣的人来说。这可能不是最干净的方法,但结果正好产生了我需要的东西。

而不是运行不可停止的forEach()循环,我只是获取整个数据库,然后定义它,并只提取值。

请参阅下面的代码,它可以有效地检查数据库中的所有值是否都包含我们的特定值。

      const token = (await Notifications.getExpoPushTokenAsync()).data;
      console.log(token);
      //---The above sits inside of a function. It is Expo's code for expo-notifications api----///
      var userListRef = firebase.database().ref("users/push_token");
      userListRef.once("value", function (snapshot) {
        createPushTokenArray(snapshot.val());
        myTokenHandler(token);
      });
      //---More code here to close function(s) and complete expo-notificaions api integration for Push Notifications---///
  var allPushTokens = [];
  function createPushTokenArray(dbState) {
    const defineDb = new Object(dbState);
    const newState = Object.values(defineDb);
    allPushTokens.push(newState);
  }
  async function myTokenHandler(myToken) {
    await createPushTokenArray();
    const cleanSearch = allPushTokens.values();
    for (const allData of cleanSearch) {
      console.log(allData);
      var checkForValue = allData.includes(myToken);
      if (checkForValue == true) {
        console.log("Push Token already stored in database.");
        break;
      } else {
        var userListRef = firebase.database().ref("users/push_token");
        var newUserRef = userListRef.push();
        var writeNewToken = newUserRef.set(myToken);
        writeNewToken;
        console.log("New Push Token stored in database.");
        break;
      }
    }
  }

其工作原理如下:

获取整个Firebase实时数据库的快照并为查询输出和我的设备的令牌创建回调:
      var userListRef = firebase.database().ref("users/push_token");
      userListRef.once("value", function (snapshot) {
        createPushTokenArray(snapshot.val());
        myTokenHandler(token);
      });
CREATE Function将上面的输出定义为一个对象,然后只获取值(删除键)并创建一个全局变量(AllPushTokens),该变量将创建一个仅包含对象值的新数组。这里的输出仍然有点乱,所以我们将进一步细分,使其在第三步中有用。
  var allPushTokens = [];
  function createPushTokenArray(dbState) {
    const defineDb = new Object(dbState);
    const newState = Object.values(defineDb);
    allPushTokens.push(newState);
  }
最后,创建一个异步函数,该函数回调我的设备的";标记&q;,等待上一个函数为我们创建一个新定义的数组,然后使用allPushTokens.values();解析新定义的数组以仅包括数组值,这为我们提供了与我的Devie&q;标记&q;相比较的可读性和有用的输出。然后,我们使用for-of开始循环遍历数据,直到满足我们的条件:(如果)我的设备的";内标识";包含在我的数据库中的某个值中,则停止循环,(否则/然后)继续将我的设备的&q;内标识&q;写入数据库。
  async function myTokenHandler(myToken) {
    await createPushTokenArray();
    const cleanSearch = allPushTokens.values();
    for (const allData of cleanSearch) {
      console.log(allData);
      var checkForValue = allData.includes(myToken);
      if (checkForValue == true) {
        console.log("Push Token already stored in database.");
        break;
      } else {
        var userListRef = firebase.database().ref("users/push_token");
        var newUserRef = userListRef.push();
        var writeNewToken = newUserRef.set(myToken);
        writeNewToken;
        console.log("New Push Token stored in database.");
        break;
      }
    }
  }

517