java如何正确地从Firebase中提取数据?
Firebase非常新,但用于大型项目
我刚刚完成了我的登录活动,我正在尝试从我的Firebase中提取(字符串)用户名和(长)分数。我需要更新数据并使其不为空
请,我需要有关MainActivity.class
的逻辑/应用程序的帮助,它通过(字符串)电子邮件和(字符串)authID以及Firebase API传递。我已经做了研究,但我已经到了一个地步,我不知道我做错了什么。在我看来一切都很好。请帮忙
提前谢谢你
我的Firebase数据如下(我认为):
{
HOME:{
user_accts:{
$uid:{
score:{(Long) num}
userName:{(String) email}
}
}
}//end of JSON unit
下面是我的UserAccount
类:
package com.frankbrenyahapps.maphunt;
public class UserAccount {
// private String firstName = null;
// private String lastName = null;
private String userName = null;
private long score = 0;
public UserAccount() {}
public UserAccount(String userName, Long score) {
// this.firstName = firstName;
// this.lastName = lastName;
this.userName = userName;
this.score = score;
}
public long getScore() {
return this.score;
}
public String getUserName() {
return userName;
}
}//end of class
以下是本课程的全部内容:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
public static final String FIREBASE_TO_HOME = "https:..";
public static final String FIREBASE_TO_HOME_TO_USERACCTS = "https:...";
private static final String FIREBASE_USER_AUTHID = "FIREBASE-AUTH-UID";
private static final String FIREBASE_USER_EMAIL = "FIREBASE-AUTH-EMAIL";
private static final String USER_PREF_AUTH = "USER-AUTH";
private static final String USER_PREF_SCORE = "USER-SCORE";
Firebase homeRef;
Firebase userRef;
private String userAuthUid;
private String userEmail;
private Long userScore;
SharedPreferences bountyHuntPrefs;
SharedPreferences.Editor prefEditor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_nav_drawer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
homeRef = new Firebase(FIREBASE_TO_HOME);
bountyHuntPrefs = getPreferences(MODE_PRIVATE);
prefEditor = bountyHuntPrefs.edit();
TextView emailTextView = (TextView) findViewById(R.id.emailTextView);
TextView scoreTextView = (TextView) findViewById(R.id.scoreTextView);
Button resetPass = (Button) findViewById(R.id.button_resetPass);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// add user to homeDB
// update the users account
// User passed auth, get them in
userEmail = getIntent().getStringExtra(FIREBASE_USER_EMAIL);
userAuthUid = getIntent().getStringExtra(FIREBASE_USER_AUTHID);
if (userAuthUid!=null) {
prefEditor.putString(USER_PREF_AUTH, userAuthUid).apply();
userAuthUid = null;
}
getUserDataFromMemory();
// TODO: Set user info into UI elements
emailTextView.setText(userEmail);
scoreTextView.setText(String.valueOf(userScore));//Long.toString(userScore)
resetPass.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Reset Password?")
.setMessage("Are you sure you want to reset your password?")
.setPositiveButton("Reset", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
homeRef.resetPassword(userEmail, new Firebase.ResultHandler() {
@Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "Request Sent", Toast.LENGTH_LONG).show();
}
@Override
public void onError(FirebaseError firebaseError) {
Toast.makeText(MainActivity.this, "Error, could not reset", Toast.LENGTH_LONG).show();
}
});
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// dismiss
}
})
.create()
.show();
}
});
}
@Override
public void onBackPressed() {
...
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
...
}
private void getUserDataFromMemory() {
userScore = bountyHuntPrefs.getLong(USER_PREF_SCORE, 0);
userRef = new Firebase(FIREBASE_TO_HOME_TO_USERACCTS).child(bountyHuntPrefs.getString(USER_PREF_AUTH, ""));
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot userSnapShot: dataSnapshot.getChildren()){
UserAccount user = userSnapShot.getValue(UserAccount.class);
userEmail = user.getUserName();
if (userScore == 0)
userScore = user.getScore();
prefEditor.putLong(USER_PREF_SCORE, userScore).apply();
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {
Toast.makeText(MainActivity.this, "Invalid Authentication", Toast.LENGTH_LONG).show();
homeRef.unauth();
homeRef = null;
finish();
}
});
UserAccount user = new UserAccount(userEmail, userScore);
userRef.setValue(user);
}
@Override
protected void onStop() {
// Log user out and kill activity
super.onStop();
homeRef.unauth();
}
@Override
protected void onResume() {
super.onResume();
userAuthUid = getPreferences(MODE_PRIVATE).getString(USER_PREF_AUTH, userAuthUid);
}
}//end of class
LOGCAT错误:
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: FATAL EXCEPTION: main
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: Process: com.frankbrenyahapps.maphunt, PID: 4796
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: com.firebase.client.FirebaseException: Failed to bounce to type
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:185)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.frankbrenyahapps.maphunt.MainActivity$2.onDataChange(MainActivity.java:219)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.firebase.client.Query$1.onDataChange(Query.java:158)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.firebase.client.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:45)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.firebase.client.core.view.DataEvent.fire(DataEvent.java:45)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.firebase.client.core.view.EventRaiser$1.run(EventRaiser.java:38)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at 安卓.os.Handler.handleCallback(Handler.java:739)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at 安卓.os.Handler.dispatchMessage(Handler.java:95)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at 安卓.os.Looper.loop(Looper.java:135)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at 安卓.app.ActivityThread.main(ActivityThread.java:5221)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:694)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.frankbrenyahapps.maphunt.UserAccount] from Integral number; no single-int-arg constructor/factory method
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromInt(StdValueInstantiator.java:320)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromNumber(BeanDeserializerBase.java:1012)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:138)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:123)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.firebase.client.DataSnapshot.getValue(DataSnapshot.java:183)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.frankbrenyahapps.maphunt.MainActivity$2.onDataChange(MainActivity.java:219)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.firebase.client.Query$1.onDataChange(Query.java:158)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.firebase.client.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:45)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.firebase.client.core.view.DataEvent.fire(DataEvent.java:45)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.firebase.client.core.view.EventRaiser$1.run(EventRaiser.java:38)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at 安卓.os.Handler.handleCallback(Handler.java:739)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at 安卓.os.Handler.dispatchMessage(Handler.java:95)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at 安卓.os.Looper.loop(Looper.java:135)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at 安卓.app.ActivityThread.main(ActivityThread.java:5221)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
11-16 20:59:43.445 4796-4796/com.frankbrenyahapps.maphunt E/AndroidRuntime: at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:694)
# 1 楼答案
你似乎只在读一个用户,但却试图在孩子们身上循环。这意味着
userSnapShot.getValue(UserAccount.class)
将在userName
和score
属性上被调用,这些属性本身不是UserAccount
对象解决方案是移除循环:
更新-对评论中问题的回答
当您没有数据的读取权限时,通常会调用
onCancelled()
方法更新用户的分数可以像
userRef .child("score").setValue(42)
一样简单。或者通过保存整个用户:user.setScore(42); userRef.setValue(user);
(您需要为此创建一个setScore()
方法)