2017-09-25 78 views
1

目的的Android - 火力地堡 - 從X節點檢索數據並將其發送到節點Y

允許用戶發送到當局報告。報告將被保存並在新的報告是由同一個用戶輸入

圖片當前數據庫不會被覆蓋

enter image description here

在簽訂當前用戶能夠存儲「事件報告」進入數據庫,但顯然當用戶提交另一個「事件報告」時,新提交的「事件報告」將覆蓋先前的「事件報告」的數據。

Desired數據庫

enter image description here

黃色突出顯示數據應該是從「用戶」子「名」,這是紅色圓圈數據

例如檢索到的數據,如果數據在紅色圓圈數據是「安倍長」,黃色突出顯示的數據也將是「安倍長」。

除此之外,當用戶簽署的當前提交「事件報告」時,每創建一個新的創建一個新的唯一密鑰。這意味着它不會覆蓋以前提交的數據。

報告片段類

import android.app.ProgressDialog; 
import android.os.Bundle; 
import android.support.annotation.NonNull; 
import android.support.v4.app.Fragment; 
import android.text.TextUtils; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.Toast; 

import com.google.android.gms.tasks.OnCompleteListener; 
import com.google.android.gms.tasks.Task; 
import com.google.firebase.auth.FirebaseAuth; 
import com.google.firebase.auth.FirebaseUser; 
import com.google.firebase.database.DatabaseReference; 
import com.google.firebase.database.FirebaseDatabase; 

import java.util.Date; 
import java.util.HashMap; 


public class ReportFragment extends Fragment { 

    private EditText jReportDatePick; 
    private EditText jReportTimeEnt; 
    private EditText jReportLocationEnt; 
    private EditText jReportDescriptionEnt; 

    private Button jReportSendBtn; 

    private FirebaseUser jReportCurrentUserID; 

    private DatabaseReference jReportByUserDatabase; 

    private ProgressDialog jReportLoad; 

    public ReportFragment() { 
     // Required empty public constructor 
    } 


    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 
     View viewRoot = inflater.inflate(R.layout.fragment_report, container, false); 

     jReportDatePick = viewRoot.findViewById(R.id.reportDatePick); 
     jReportTimeEnt = viewRoot.findViewById(R.id.reportTimeEnt); 
     jReportLocationEnt = viewRoot.findViewById(R.id.reportLocationEnt); 
     jReportDescriptionEnt = viewRoot.findViewById(R.id.reportDescriptionEnt); 

     jReportSendBtn = viewRoot.findViewById(R.id.reportSendBtn); 

     jReportLoad = new ProgressDialog(getActivity()); 

     jReportSendBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       String userReportDate = jReportDatePick.getText().toString(); 
       String userReportTime = jReportTimeEnt.getText().toString(); 
       String userReportLocation = jReportLocationEnt.getText().toString(); 
       String userReportDescription = jReportDescriptionEnt.getText().toString(); 

       if(!TextUtils.isEmpty(userReportDate)&& 
         !TextUtils.isEmpty(userReportTime)&& 
         !TextUtils.isEmpty(userReportLocation)&& 
         !TextUtils.isEmpty(userReportDescription)){ 
        submitReport(userReportDate, userReportTime, userReportLocation, userReportDescription); 
        jReportLoad.setTitle("Sending Report"); 
        jReportLoad.setMessage("Please wait while the report is being sent"); 
        jReportLoad.setCanceledOnTouchOutside(false); 
        jReportLoad.show(); 
       }else{ 
        jReportLoad.dismiss(); 
        Toast.makeText(getActivity(), "Report failed to be sent due to empty inputs", Toast.LENGTH_SHORT).show(); 
       } 

      } 
     }); 

     return viewRoot; 
    } 

    private void submitReport(final String userReportDate,final String userReportTime, 
           final String userReportLocation,final String userReportDescription) { 

     jReportCurrentUserID = FirebaseAuth.getInstance().getCurrentUser(); 
     final String reportUserID = jReportCurrentUserID.getUid(); 
     jReportByUserDatabase = FirebaseDatabase.getInstance().getReference().child("Incident Reports").child(reportUserID); 

     HashMap<String, String> incidentReportUser = new HashMap<>(); 
     incidentReportUser.put("date", userReportDate); 
     incidentReportUser.put("time", userReportTime); 
     incidentReportUser.put("location", userReportLocation); 
     incidentReportUser.put("description", userReportDescription); 

     jReportByUserDatabase.setValue(incidentReportUser).addOnCompleteListener(new OnCompleteListener<Void>() { 
      @Override 
      public void onComplete(@NonNull Task<Void> task) { 
       if(task.isSuccessful()){ 
        jReportLoad.dismiss(); 
        Toast.makeText(getActivity(), "Report was Sent", Toast.LENGTH_SHORT).show(); 
        jReportDatePick.setText(""); 
        jReportTimeEnt.setText(""); 
        jReportLocationEnt.setText(""); 
        jReportDescriptionEnt.setText(""); 
       }else{ 
        jReportLoad.dismiss(); 
        Toast.makeText(getActivity(), "Report failed to be sent", Toast.LENGTH_SHORT).show(); 
       } 
      } 
     }); 
    } 
} 

附加評論

  • 報告片段是如何工作的

我不打算爲當前登錄的用戶能夠提交他們的名字,這將創建一個寶用戶將其他人的姓名輸入到「事件報告」中。我打算檢索「當前用戶已登錄」名稱並自動將其輸入到「事件報告」中。

  • 如何報告片段編碼

而不是把jReportByUserDatabase.setValue(incidentReportUser)同時使用Map<String, Object>我試圖把.updateChildren的。問題是,每個數據是下一個「唯一ID」,將「事故報告」下保存進入數據樹


解決方案中的問題

的幫助下由Cadet和JavaBanana編寫

實現「For循環DataSnapshot」以遍歷數據並檢索所需的數據,同樣使用「用戶級」,其中包含了姓名,地址,狀態等

private void submitReport(final String userReportDate,final String userReportTime, 
          final String userReportLocation,final String userReportDescription) { 

DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference(); 
dbRef.child("Users").addListenerForSingleValueEvent(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     for (DataSnapshot snapshot : dataSnapshot.getChildren()) { 
      Users user = snapshot.getValue(Users.class); 
      HashMap<String, String> incidentReportUser = new HashMap<>(); 
      incidentReportUser.put("name", user.name); 
      incidentReportUser.put("date", userReportDate); 
      incidentReportUser.put("time", userReportTime); 
      incidentReportUser.put("location", userReportLocation); 
      incidentReportUser.put("description", userReportDescription); 

      jReportCurrentUserID = FirebaseAuth.getInstance().getCurrentUser(); 
      final String reportUserID = jReportCurrentUserID.getUid(); 
      jReportByUserDatabase = FirebaseDatabase.getInstance().getReference().child("Incident Reports").child(reportUserID); 
      jReportByUserDatabase.push().setValue(incidentReportUser).addOnCompleteListener(new OnCompleteListener<Void>() { 
       @Override 
       public void onComplete(@NonNull Task<Void> task) { 
        if(task.isSuccessful()){ 
         jReportLoad.dismiss(); 
         Toast.makeText(getActivity(), "Report was Sent", Toast.LENGTH_SHORT).show(); 
         jReportDatePick.setText(""); 
         jReportTimeEnt.setText(""); 
         jReportLocationEnt.setText(""); 
         jReportDescriptionEnt.setText(""); 
        }else{ 
         jReportLoad.dismiss(); 
         Toast.makeText(getActivity(), "Report failed to be sent", Toast.LENGTH_SHORT).show(); 
        } 
       } 
      }); 
     } 
    } 
    @Override 
    public void onCancelled(DatabaseError databaseError) { 
    } 
}); 
} 

回答

1

好了,主要的問題與你的設計,你是存儲用戶的ID下的報告,其中火力顯然會覆蓋。

您可以生成隨機密鑰來存儲報告,並將報告設置爲數據庫中生成的密鑰。

public class Report { 
    String reportId; // This is important 
    String reporterId; //This is important 
    String reporterName; 
    String userType; 
    String status; 
    String address; 
    String neibourhood; 
    String image; 
} 

DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference("Incident Reports"); 
String reportId = dbRef.push().getKey(); //This generates a new key and returns it 
Report report = new Report("report id", "reporter id", "other stuff"... "etc"); 
dbRef.child(reportId).setValue(report); 

來檢索用戶

DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference(); 
dbRef.child("Users").addListenerForSingleValueEvent(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     //Loop through the retrieved user data 
     for (DataSnapshot snapshot : dataSnapshot.getChildren()) { 
      User user = snapshot.getValue(User.class); 
      System.out.println(user.name); 
     } 
    } 
    @Override 
    public void onCancelled(DatabaseError databaseError) {} 
}); 
+0

謝謝你的回答!感謝您向我展示生成新密鑰的方式:String reportId = dbRef.push()。getKey(); '但是如果我想從**紅色圓圈**數據中檢索「名稱」怎麼辦? – Student

+0

「用戶」節點或「事件報告」節點中的用戶名? – JavaBanana

+0

「用戶」節點中的用戶名。當前數據庫的**圖片是我目前使用的圖片**,我希望生成**圖片的期望數據庫**。用戶的「姓名」不是由當前用戶輸入,而是當他/她提交「事件報告」時從當前用戶檢索到的 – Student

2

寫它通過這種方式 (push將值,而不是壓倒一切)。

jReportByUserDatabase.push()setValue(incidentReportUser)

另外,我建議,使包含用戶字段還報告節點。就像將它們結合到扁平節點一樣

enter image description here

+0

OMG THANK YOU SO MUCH的名字!一個'.push()'幫助解決了90%的問題!我從來沒有想過它!但是有沒有辦法讓我獲得當前用戶的「名稱」?請幫助我= D – Student

+0

「當前」用戶的定義是什麼?一個人做了最新的報道? – Cadet

+0

是的!!!例如,「John Smith」是當前用戶登錄到應用程序。 「約翰史密斯」將能夠發送儘可能多的報告,如他所願。但我只想從**紅色圓圈**數據中檢索他的「姓名」,如**所需數據庫的圖片** – Student

相關問題