防止新数据快照创建其他子级

时间:2019-04-15 20:25:56

标签: c# unity3d firebase-realtime-database

我正在尝试将数据快照发送到Firebase数据库。多数情况下都能正常工作,但是我遇到了一个问题,不是将子对象直接附加到其预期的父对象上,而是将它们添加到附加到预期的父对象的另一个孩子上。

public void CreateCampaign()
{
   campaignName = campaignNameText.text;
   ownerName = pInfo.userName;

   if (string.IsNullOrEmpty(campaignName))
   {
      DebugLog("invalid campaign name.");
      return;
   }

   DebugLog(String.Format("Attempting to add campaign ", campaignName, ownerName));

   DatabaseReference reference = FirebaseDatabase.DefaultInstance.GetReference("Users").Child(pInfo.userName).Child("Campaigns").Push();

   DebugLog("Running Transaction...");

   reference.RunTransaction(AddCampaignTransaction)
     .ContinueWith(task =>
   {
      if (task.Exception != null)
      {
         DebugLog(task.Exception.ToString());
      }
      else if (task.IsCompleted)
      {
         DebugLog("Campaign " + campaignName + " added successfully.");
      }
   });
}
TransactionResult AddCampaignTransaction(MutableData mutableData)
{
   List<object> Campaigns = mutableData.Value as List<object>;

   if (Campaigns == null)
   {
      Campaigns = new List<object>();
   }


   Dictionary<string, object> newCampaignMap = new Dictionary<string, object>();
   newCampaignMap["CampaignName"] = campaignName;
   newCampaignMap["Owner"] = pInfo.userName;
   newCampaignMap["Members"] = 0;
   Campaigns.Add(Child(newCampaignMap));

   mutableData.Value = Campaigns;

   return TransactionResult.Success(mutableData);

   InitializeCampaign();
}

因此,我所有的数据都添加到了数据库中,但是我的数据结构看起来像这样。

  • 用户
    • 用户名
      • 广告活动
        • pushID
          • 0
            • 广告系列名称
            • 所有者名称
            • Memebrs

我需要知道的是;如何防止将孩子“ 0”放在pushID和要添加的三个键之间,以便我的数据结构如下所示。

  • 用户
    • 用户名
      • 广告活动
        • pushID
          • 广告系列名称
          • 所有者名称
          • 会员

2 个答案:

答案 0 :(得分:0)

您正在使用单个元素推送List。 0表示它是第0个元素。如果List中还有更多元素,则会看到1、2等。

您应该替换此行

mutableData.Value = Campaigns;

与此行

mutableData.Value = newCampaignMap;

,然后重试。

您还可以摆脱不再使用的Campaigns等。

答案 1 :(得分:0)

就像Gazihan's answer中提到的那样,问题是由于将列表(广告系列)上传到数据库而不是您想要的节点(newCampaignMap)而引起的。

事务用于需要按顺序修改服务器上已经存在的数据的情况。由于您使用Push()生成了一个数据库引用,因此不需要这样做,而可以使用SetValueAsync

在上述AddCampaignTransaction的代码中,您将生成一个空列表(因为没有数据),将newCampaignMap的值添加到该列表中,然后将该列表上传到数据库中,而不是只是新的价值。在此函数中,您还将利用CreateCampaign函数中的共享内部变量,这是一种不好的做法,尤其是在处理异步代码时。

相反,我建议使用以下代码:

public void CreateCampaign()
{
    // take local copies of values
    string campaignName = campaignNameText.text;
    string ownerName = pInfo.userName;

    if (string.IsNullOrEmpty(campaignName))
    {
        DebugLog("invalid campaign name.");
        return;
    }

    DebugLog(String.Format("Attempting to add campaign '{0}' for '{1}'... ", campaignName, ownerName));

    // structure data
    Dictionary<string, object> newCampaignMap = new Dictionary<string, object>();
    newCampaignMap["CampaignName"] = campaignName;
    newCampaignMap["Owner"] = pInfo.userName;
    newCampaignMap["Members"] = 0;

    DebugLog("Adding to database... ");
    // get reference and upload data
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.GetReference("Users").Child(pInfo.userName).Child("Campaigns").Push();
    reference.SetValueAsync(newCampaignMap)
        .ContinueWith(task =>
    {
        if (task.IsFaulted)
        {
            DebugLog(task.Exception.ToString());
            return;
        }

        DebugLog("Campaign " + campaignName + " added successfully.");
    });
}