Expo 和 Firebase Realtime DB - 在写入数据库之前读取值并确认特定值不存在

Expo and Firebase Realtime DB - Read values and confirm a particular value does not exist before writing to database

我有一个正常运行的 React Native Expo 应用程序可以与我的 Firebase 实时数据库交互。简而言之,在将该值(再次)作为新记录写入数据库之前,我很难找到一种检查所有子值以查看值是否存在的方法。

我一直在我的 App.js 中从 Expo 的推送通知 API 中获取“ExponentPushToken”,然后在同一函数中使用以下代码立即将新记录写入我的 Firebase 实时数据库从 Expo 的推送通知注册推送通知 API:

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

我还有以下代码读取数据库并记录以控制台我需要能够将所有输出值与上述“令牌”值进行比较的正确信息:

var userListRef = firebase.database().ref("users/push_token");
  userListRef.on("value", function (snapshot) {
    snapshot.forEach(function (child) {
      console.log(child.val());
    });
  });

我继续碰壁的地方是尝试获取获取的“令牌”并确认它在我的 Firebase 中还不是“child.val()”(数据库中的现有值)在我 .push().set() 在所述数据库中创建新记录之前的实时数据库。我也希望能够登录到控制台进行验证。下面的代码不起作用......我在这里的尝试是尝试 .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.");
    }
  }

我无数次试图在这一切中取得任何进展的尝试都是徒劳的。作为参考,下面是数据库结构(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;
      }
    }
  }

它是这样工作的:

  1. 获取整个 Firebase 实时数据库的“快照”并为查询输出和我设备的“令牌”创建回调:
      var userListRef = firebase.database().ref("users/push_token");
      userListRef.once("value", function (snapshot) {
        createPushTokenArray(snapshot.val());
        myTokenHandler(token);
      });
  1. 创建函数以将上述输出定义为一个对象,然后只获取值(删除键)并创建一个全局变量 (allPushTokens),该变量将创建一个仅包含对象值的新数组。这里的输出仍然有点混乱,所以我们将进一步分解它以使其在第三步中有用。
  var allPushTokens = [];
  function createPushTokenArray(dbState) {
    const defineDb = new Object(dbState);
    const newState = Object.values(defineDb);
    allPushTokens.push(newState);
  }
  1. 最后,创建一个异步函数来回调我设备的“令牌”,等待前面的函数为我们创建一个新定义的数组,然后解析新定义的数组以仅包含数组值使用 allPushTokens.values(); 与我的设备的“令牌”相比,它为我们提供了可读且对我们有用的输出。然后我们使用 for-of 开始循环数据,直到满足我们的标准:(如果)我的设备的“令牌”包含在我的数据库中某处的值,停止循环,(else/then)继续将我设备的“令牌”写入数据库。
  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;
      }
    }
  }