基本上,我正在制作一个使用firebase
并尝试检索real-time database
的应用程序,就像我将图像存储在firebase storage
中并复制“下载URL”链接并将其粘贴到firebase数据库中一样,以便每次运行时在我的应用中,应该有一张图片,标题和说明应该在该图片下。我基本上想将图像,标题和说明添加到Firebase数据库中,然后在应用程序中进行检索。
Activity_main:-
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recyclerview">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
个人行:-
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher_round"
android:id="@+id/image"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:text="title"
android:id="@+id/title"/>
<TextView
android:layout_width="match_parent"
android:textColor="#000000"
android:layout_height="wrap_content"
android:text="description"
android:id="@+id/description"/>
</LinearLayout>
</android.support.v7.widget.CardView>
Firebase数据库规则:-
{
“规则”:{
“ .read”:“ true”,
“ .write”:“ true”
}
}
Firebase存储规则:-
service firebase.storage {
match /b/{bucket}/o {
match[enter image description here][1] /{allPaths=**} {
// Allow access by all users
allow read, write;
}
}
}
主要活动: -
package com.namy86.dtunews;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.squareup.picasso.Picasso;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private DatabaseReference myref;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView=(RecyclerView)findViewById(R.id.recyclerview);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
myref= FirebaseDatabase.getInstance().getReference().child("/blog");
FirebaseRecyclerAdapter<Blog,BlogViewHolder> recyclerAdapter=new FirebaseRecyclerAdapter<Blog,BlogViewHolder>(
Blog.class,
R.layout.individual_row,
BlogViewHolder.class,
myref
) {
@Override
protected void populateViewHolder(BlogViewHolder viewHolder, Blog model, int position) {
viewHolder.setTitle(model.getTitle());
viewHolder.setDescription(model.getDescription());
viewHolder.setImage(model.getImage());
}
};
recyclerView.setAdapter(recyclerAdapter);
}
public static class BlogViewHolder extends RecyclerView.ViewHolder {
View mView;
TextView textView_title;
TextView textView_decription;
ImageView imageView;
public BlogViewHolder(View itemView) {
super(itemView);
mView=itemView;
textView_title = (TextView)itemView.findViewById(R.id.title);
textView_decription = (TextView) itemView.findViewById(R.id.description);
imageView=(ImageView)itemView.findViewById(R.id.image);
}
public void setTitle(String title)
{
textView_title.setText(title+"");
}
public void setDescription(String description)
{
textView_decription.setText(description);
}
public void setImage(String image)
{
Picasso.with(mView.getContext())
.load(image)
.into(imageView);
}
}
}
博客(活动):-
package com.namy86.dtunews;
public class Blog {
private String title,description,image;
public Blog() {
}
public Blog(String title, String description, String image) {
this.title = title;
this.description = description;
this.image = image;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
Firebase数据库结构:-
demofirebase-1faa
帖子1
-Description1="First Post"
-Image1="https://firebasestorage.googleapis.com/v0/b/demofirebase-1faaa.appspot.com/o/Unknown.jpg?alt=media&token=6f5ade3c-d615-4871-90a0-1b4a55e6e00c"
-Title1="Namy"
邮政2
-Description2="Second Post"
-Image2="https://firebasestorage.googleapis.com/v0/b/demofirebase-1faaa.appspot.com/o/Unknown.jpg?alt=media&token=6f5ade3c-d615-4871-90a0-1b4a55e6e00c"
-Title2="Naman"
最佳答案
假设您已经正确配置了项目,则可以通过获取引用,创建新节点(如Alex Mamo所说的,没有特定节点就无法发送数据)并将对象放入其中来将数据发送到Firebase。见下文:
// get your reference
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
// refer your child and use push to generate a new unique node, then put your object
reference.child("blog").push().setValue(blog);
连接Firebase和适配器可以通过两种方式完成:在检索对象时显示对象或一次显示所有对象。
逐对象:
创建一个界面来接收物品:
public interface ItemListener<T> {
void onItemAdded(@NonNull final T item);
void onItemRemoved(@NonNull final T item);
}
在您的DAO中,创建一种从博客节点获取所有对象的方法:
public void getBlogList(@NonNull final ItemListener listener) {
FirebaseDatabase.getInstance().getReference().child("blog").orderByKey()
.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
final Blog blog = dataSnapshot.getValue(Blog.class);
listener.onItemAdded(blog);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
final Blog blog = dataSnapshot.getValue(Blog.class);
listener.onItemRemoved(blog);
}
@Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {}
@Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
@Override public void onCancelled(DatabaseError databaseError) {}
});
}
在您的适配器内部,在构造函数中调用上述方法,将接收到的博客发送到列表中并通知:
public class Adapter extends RecyclerView.Adapter<BlogViewHolder> {
private List<Blog> mBlogList;
public Adapter() {
getBlogList(new ItemListener<Blog>() {
@Override
public void onItemAdded(@NonNull final Blog blog) {
mBlogList.add(blog);
notifyItemInserted(mBlogList.size);
}
@Override
public void onItemRemoved(@NonNull final Blog blog) {
for (Integer i = 0; i < mBlogList.size(); i++) {
final Blog innerBlog = mBlogList.get(i);
// since you don't store a key, you gotta check all attributes
if (innerBlog.getTitle.equals(blog.getTitle) &&
innerBlog.getDescription.equals(blog.getDescription) &&
innerBlog.getImage.equals(blog.getImage)) {
mBlogList.remove(innerBlog);
notifyItemRemoved(i);
}
}
}
});
}
@Override
public BlogViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new BlogViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.individual_row, parent, false));
}
@Override
public void onBindViewHolder(BlogViewHolder holder, int position) {
final Blog blog = holder.get(position);
holder.setTitle(blog.getTitle());
holder.setDescription(blog.getDescription());
holder.setImage(blog.getImage());
}
@Override
public int getItemCount() {
return mBlogList.size();
}
}
一次所有对象:
创建一个接口以接收列表:
public interface ListListener<T> {
void onListRetrieved(@NonNull final List<T> list);
}
在您的DAO中,创建一种从博客节点一次获取所有对象的方法:
public void getBlogList(@NonNull final ListListener listener) {
final List<Blog> blogList = new ArrayList<>();
FirebaseDatabase.getInstance().getReference().child("blog")
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (final DataSnapshot innerDataSnapshot : dataSnapshot.getChildren()) {
final Blog blog = innerDataSnapshot.getValue(Blog.class);
blogList.add(blog);
}
listener.onListRetrieved(blogList);
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
}
在适配器内部,在构造函数中调用上述方法,克隆接收到的列表并通知:
public class Adapter extends RecyclerView.Adapter<BlogViewHolder> {
private List<Blog> mBlogList;
public Adapter() {
getBlogList(new ListListener<Blog>() {
@Override
public void onListRetrieved(@NonNull final List<Blog> blogList) {
mBlogList.addAll(blogList);
notifyDataSetChanged();
}
});
}
// same code as first Adapter
}
然后,您可以将此适配器添加到您的
RecyclerView
中:@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
recyclerView.setAdapter(new Adapter());
}