写在之前
一开始连接firebase碰到了几个问题。
- 首先是按照官网步骤把firebase连接到android app上一直显示连接不上。但是如果看android studio的tool->firebase->realtime database里面显示的是已经connect上了。所以可以skip 掉connect 的那一步
- 使用realdatabase的时候,按照官网
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");myRef.setValue("Hello, World!");myRef.addValueEventListener(new ValueEventListener() {
@Overridepublic void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again// whenever data at this location is updated.String value = dataSnapshot.getValue(String.class);Log.d(TAG, "key is: " + dataSnapshot.getKey());Log.d(TAG, "Value is: " + value);}@Overridepublic void onCancelled(DatabaseError error) {
// Failed to read valueLog.w(TAG, "Failed to read value.", error.toException());}});
log里面打印出来了key和value,但是database中仍然未显示。在网上查询,有说要重启的,有说要关掉adblock的,都试了一下没有用。结果解决办法是…我在windows上重新连接,就成功了…
Realdatabase Asynchronous
存在firebase里面的data格式是:
想要监听数据,则要使用addValueEventListener
一开始的错误代码如下:
public class FolderActivity extends AppCompatActivity {
private ActivityFolderBinding mBinding;private RecyclerView recyclerView;private RecyclerView.Adapter mAdapter;FirebaseDatabase database;final String TAG = "Database";@Overrideprotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);mBinding= DataBindingUtil.setContentView(this, R.layout.activity_folder);final List<Event> eventsList = new ArrayList<>();database= FirebaseDatabase.getInstance();//定位到Eventfinal DatabaseReference eventRef = database.getReference().child("Event");Log.w(TAG,"Completed connection");eventRef.addValueEventListener(new ValueEventListener() {
@Overridepublic void onDataChange(@NonNull DataSnapshot datasnapshot) {
// 提取数据String usernamePublished = datasnapshot.child("usernamePublished").getValue().toString();String datePublished = datasnapshot.child("datePublished").getValue().toString();String eventDate =datasnapshot.child("eventDate").getValue().toString();String eventTime =datasnapshot.child("eventTime").getValue().toString();String address = datasnapshot.child("address").getValue().toString();//加入到eventsList里面eventsList.add(new Event(usernamePublished,datePublished,eventDate,eventTime,address));Log.w(TAG,"Completed saving data");}@Overridepublic void onCancelled(@NonNull DatabaseError error) {
}});eventsList.add(new Event("旋转木马的悲伤1","2020-02-19","2020-02-20","18:00pm","University of Melbourne"));Log.w(TAG,"second"+eventsList.get(0).getusernamePublished ());final FolderCellAdapter adapter = new FolderCellAdapter(eventsList);mBinding.eventRecycler.setLayoutManager(new GridLayoutManager(this,1));mBinding.eventRecycler.setAdapter(adapter);}
}
但是当查询log的时候,他的打印顺序是:
“Completed connection”
“旋转木马的悲伤1” (此时eventslist只有一个)
“Completed saving data"(此时eventslist中有两个)
但是app会报错,或者只显示我下面添加的”旋转木马的悲伤1“。查询以后,发现是因为onDataChange是一个asynchronous的方式,当数据从realdatabase加载过来的时候,程序会继续执行。所以其实adapter带进的eventlist是只有一个事件的list。
解决办法
所以解决办法是首先adapter和list都要放在addValueEventListener
之前,这样我们可以在onDataChange
的时候用到他。
在加载数据之后,告知我们的adapter数据变了。这样他就可以显示出来了。具体代码如下
public class FolderActivity extends AppCompatActivity {
private ActivityFolderBinding mBinding;private RecyclerView recyclerView;private RecyclerView.Adapter mAdapter;FirebaseDatabase database;final String TAG = "Database";@Overrideprotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_folder);mBinding= DataBindingUtil.setContentView(this, R.layout.activity_folder);
// recyclerView = findViewById(R.id.event_recycler);final List<Event> eventsList = new ArrayList<>();eventsList.add(new Event("旋转木马的悲伤1","2020-02-19","2020-02-20","18:00pm","University of Melbourne"));// 这里提前创建final FolderCellAdapter adapter = new FolderCellAdapter(eventsList);mBinding.eventRecycler.setLayoutManager(new GridLayoutManager(this,1));mBinding.eventRecycler.setAdapter(adapter);database= FirebaseDatabase.getInstance();final DatabaseReference eventRef = database.getReference().child("Event");eventRef.addValueEventListener(new ValueEventListener() {
@Overridepublic void onDataChange(@NonNull DataSnapshot datasnapshot) {
String usernamePublished = datasnapshot.child("usernamePublished").getValue().toString();String datePublished = datasnapshot.child("datePublished").getValue().toString();String eventDate =datasnapshot.child("eventDate").getValue().toString();String eventTime =datasnapshot.child("eventTime").getValue().toString();String address = datasnapshot.child("address").getValue().toString();eventsList.add(new Event(usernamePublished,datePublished,eventDate,eventTime,address));//记得告知adapteradapter.notifyDataSetChanged();}@Overridepublic void onCancelled(@NonNull DatabaseError error) {
}});Log.w(TAG,"second"+eventsList.get(0).getDatePublished());}