【问题标题】:Android Firebase: Overwrite value instead of create an new entryAndroid Firebase:覆盖值而不是创建新条目
【发布时间】:2021-04-10 16:04:23
【问题描述】:

我正在为我在 GitHub 上找到的想要继续开发的项目而苦苦挣扎。这只是出于自我教育的目的,因为我想在 firebase 上更高效地工作。这是项目及其整个代码。 -> Project

现在我的问题。完成游戏后,该应用每次都会在 Firebase 中创建一个新条目。这些行在 SingeWordActivity.class 中,它们正在为 firebase 创建输出:

    DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference(Constants.USER_SCORE);
    String id = databaseReference.push().getKey();
    User user = new User(id, getSharedPreferences(Constants.USER_PREFERENCE, Context.MODE_PRIVATE).getString(Constants.USER_NICK, getString(R.string.OK)),
            numberOfLetters / 5, numberOfLetters, true);
    if (id != null) {
        databaseReference.child(id).setValue(user);
    }
}

常量只是链接在不同的类中,如下所示:

public class Constants {
public static final int BANNER_SCREEN_TIMEOUT = 3000;
public static final int ANIMATION_DURATION = 1500;
public static final String PREF_FIRST_TIME = "isFirstTime";
public static final String USER_NICK = "userNick";
public static final String USER_PREFERENCE = "userPref";
public static final String USER_SCORE = "score-list";
public static final String IS_FIRST_LOGIN = "isFirst";
public static final String GAME_TYPE = "game_type";
public static final String PARAGRAPH = "paragraph";
public static final String SINGLE_WORD = "single_word";


public static int MILLIS_IN_FUTURE = 60000;
public static final int COUNTDOWN_INTERVAL = 1000;

}

这是最后在火力基地中的样子:

有没有办法在 Activity 之后,firebase 中的每个值(userScore,singelWord,userLetterCount)都会更新,并且这些值与“userName”相关联?

因此,firebase 中不可能有重复的 userNames

-----更新:-----

要仅在(分数)值大于现有值时更新 Firebase,您必须更改 Firebase 设置。如下所示:

firebase code

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    每次您在 Firebase 实时数据库上调用 push() 时,它都会生成一个新的唯一位置和密钥。所以这一行,生成一个新的密钥:

    String id = databaseReference.push().getKey();
    

    如果要更新现有节点,则需要知道该节点的 id,而不是生成新的唯一节点。例如,如果您想更新 Peter 的分数,您可以使用查询来查找 Peter 的现有节点:

    DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference(Constants.USER_SCORE);
    Query query = databaseReference.orderByChild("userName").equalTo("Peter")
    query.addListenerForSingleValueEvent(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot resultsSnapshot) {
        for (DataSnapshot userSnapshot: resultsSnapshot.getChildren()) {
          User user = new User(id, getSharedPreferences(Constants.USER_PREFERENCE, Context.MODE_PRIVATE).getString(Constants.USER_NICK, getString(R.string.OK)),
            numberOfLetters / 5, numberOfLetters, true);
          userSnapshot.getReference().setValue(user);
        }
      }
    
      @Override
      public void onCancelled(DatabaseError databaseError) {
        throw databaseError.toException();
      }
    }
    

    您会注意到上面我说的是“节点”,因为可能有多个子节点,其中userNamePeter。如果这是您想要防止的情况,您可以考虑使用用户名作为节点的 ID。如果 Peter 的分数存储在 /score-list/Peter 下,则始终只能有一个分数 - 因为每个节点路径都保证是唯一的。

    【讨论】:

      【解决方案2】:

      每次使用push 时,它都会生成一个新的唯一密钥。所以如果你想根据userName更新值,你可以这样做:

      String userName = getSharedPreferences(Constants.USER_PREFERENCE, Context.MODE_PRIVATE).getString(Constants.USER_NICK, getString(R.string.OK))
      
      User user = new User(userName, numberOfLetters / 5, numberOfLetters, true);
      databaseReference.child(userName).setValue(user);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-13
        • 2014-05-18
        • 1970-01-01
        • 1970-01-01
        • 2015-11-20
        • 1970-01-01
        相关资源
        最近更新 更多