android - Android Java Firebase 像地图一样保存数据
问题描述
我正在尝试将我的用户指向我的火力基地。这张图就是我想要的。
我想添加我的用户结果,如地图。这是我如何调用我的方法下面的代码。
checkUserScoreIsExist(gameUser, new UserExistsCallback() {
@Override
public void onCallback(boolean isExisting) {
saveUserScoreToFirebase(gameUser, currentGame, isExisting,
new ScoreUserCallback() {
@Override
public void onCallback(boolean isScoreUserSaveSuccess) {
if(isScoreUserSaveSuccess)
Toast.makeText(GameActivity.this, "Score saved successfully", Toast.LENGTH_LONG).show();
else
Toast.makeText(GameActivity.this, "Score can not saved successfully", Toast.LENGTH_LONG).show();
}
});
}
});
这些是我的方法。
private void checkUserScoreIsExist(final User user, final UserExistsCallback callback) {
Log.d(TAG, "User score checking.");
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
DocumentReference docIdRef = rootRef.collection("scores").document(user.getUsername());
docIdRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
assert document != null;
isScoreExist = document.exists();
} else {
Log.d(TAG, "Failed with: ", task.getException());
}
callback.onCallback(isScoreExist);
}
});
}
private void saveUserScoreToFirebase(User user, Game game, boolean isScoreExist, final ScoreUserCallback callback) {
Log.d(TAG, "Saving user to database.");
Map<String, Object> gameMap = new HashMap<>();
gameMap.put("gameResult", game.calculateResult());
if(isScoreExist){
db.collection("scores").document(user.getUsername())
.update(gameMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
isSaveScoreSuccess = task.isSuccessful();
callback.onCallback(isSaveScoreSuccess);
}
});
}else{
db.collection("scores").document(user.getUsername())
.set(gameMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
isSaveScoreSuccess = task.isSuccessful();
callback.onCallback(isSaveScoreSuccess);
}
});
}
当我这样尝试时,我无法保存我的新结果,它将被覆盖。我怎样才能获得像我的形象一样的数据库。请帮助我如何做到这一点。非常感谢大家。
解决方案
问题是,为了保持您记住的结构,您必须将整个文档更新到 Firestore。
因此,在更新分数时,您的应用程序的理想流程应该是执行 aget()
以获取已作为地图存在的完整文档,将新分数添加到地图中,然后对其进行更新。您可以通过将saveUserScoreToFirebase
函数更改为以下内容来做到这一点:
编辑:根据我们在聊天中的对话,您还想向该集合添加一个额外的字段,称为 gameTime,并且您有一个获取游戏模型对象的函数,该对象包含 gameResults 和 gameTime,并使其到一个 json 中,这简化了我们的生活,因为您需要做的就是在更新之前将该 json 添加到地图中。请注意,我之前提出的所有观点仍然有效,因此代码将如下所示:
private void saveUserScoreToFirebase(User user, Game game, boolean isScoreExist, final ScoreUserCallback callback) {
Log.d(TAG, "Saving user to database.");
Map<String, Object> gameMap = new HashMap<>();
if(isScoreExist){
db.collection("scores").document(user.getUsername())
.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
// Document found in the offline cache
DocumentSnapshot document = task.getResult();
gameMap = document.getData();
// if you are starting with # 0 you can take the '+1' from this
gameMap.put(String.valueOf(gameMap.size()+1), game.toJSON());
db.collection("scores").document(user.getUsername())
.update(gameMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
isSaveScoreSuccess = task.isSuccessful();
callback.onCallback(isSaveScoreSuccess);
}
});
} else {
Log.d(TAG, "Getting previous score failed with following exception: ", task.getException());
}
}
});
}else{
gameMap.put(String.valueOf(gameMap.size()+1), game.toJSON());
db.collection("scores").document(user.getUsername())
.set(gameMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
isSaveScoreSuccess = task.isSuccessful();
callback.onCallback(isSaveScoreSuccess);
}
});
}
}
注意:这是未经测试的,但如果它不能立即工作,应该是您考虑前面描述的逻辑的一个很好的起点。
推荐阅读
- wordpress - 带有 Fullpage.js 的 WordPress 包含页脚
- c++ - 有效地对 std::vector 中的所有项目执行下限功能
- .net - nuget 打包程序集时,nuspec 文件中的 $version$ 令牌未从 AssemblyInfo.cs 读取
- debugging - 如何使用 gdb 在目标 ARM MCU 上调试闪存程序
- php - 错误:SQLSTATE [HY093]:无效的参数号:未定义第一年学生的参数
- python-3.x - 为什么在更新哈希对象时会出现 TypeError?
- excel - 绘图问题
- sprite-kit - 以编程方式更改场景编辑器中的纹理
- c++ - 通过参数传递任何函数
- google-sheets - 比较 Google 表格中的 2 个范围并返回不在第一个范围内的值