I just started out with Firebase and its been great so far. However, when I try to hook my data in a card view using Firebase UI and Firebase RecyclerAdapter, I get the following error on my log cat which says
$ E/RecyclerView: No adapter attached; skipping layout
This is my MainActivity.java
package helloworld.firebase.com.helloworld;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.GoogleAuthProvider;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import org.w3c.dom.Text;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
TextView text1, text2 ;
EditText edittitle, editdesc;
Button btn, post;
ListView mUserList;
private RecyclerView mRecyclerView;
private SignInButton mGooglebtn;
private static final int RC_SIGN_IN = 1;
private GoogleApiClient mGoogleApiClient;
private DatabaseReference mDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListner;
private FirebaseRecyclerAdapter firebaseRecyclerAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.blog_list);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(firebaseRecyclerAdapter);
mGooglebtn = (SignInButton) findViewById(R.id.googleBtn);
edittitle = (EditText) findViewById(R.id.edit_title);
editdesc = (EditText) findViewById(R.id.edit_desc);
post = (Button) findViewById(R.id.post);
post.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startPosting();
}
});
mAuth = FirebaseAuth.getInstance();
mAuthListner = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() != null) {
Toast.makeText(MainActivity.this, "LOGGED IN", Toast.LENGTH_SHORT).show();
startActivity(new Intent(MainActivity.this, AccountActivity.class));
}
}
};
mDatabase = FirebaseDatabase.getInstance().getReference().child("Blog");
final String userID = mDatabase.push().getKey();
// Configure Google Sign In
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Toast.makeText(MainActivity.this, "ERROR", Toast.LENGTH_SHORT).show();
}
})
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
mGooglebtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
signIn();
}
});
private void startPosting() {
String name = edittitle.getText().toString().trim();
String desc = editdesc.getText().toString().trim();
DatabaseReference newPost = mDatabase.child("Blog").push();
newPost.child("title").setValue(name);
newPost.child("desc").setValue(desc);
}
protected void OnStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListner);
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<User, BlogViewHolder>(User.class,
R.layout.blog_row,
BlogViewHolder.class,
mDatabase) {
@Override
protected void populateViewHolder(BlogViewHolder viewHolder, User model, int position) {
viewHolder.setTitle(model.getTitle());
viewHolder.setDesc(model.getDesc());
}
};
mRecyclerView.setAdapter(firebaseRecyclerAdapter);
}
public static class BlogViewHolder extends RecyclerView.ViewHolder {
View mView;
public BlogViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setTitle(String title) {
TextView posttitle = (TextView) mView.findViewById(R.id.post_title);
posttitle.setText(title);
}
public void setDesc (String desc) {
TextView postdesc = (TextView) mView.findViewById(R.id.post_desc);
postdesc.setText(desc);
}
}
private void signIn() {
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
// Google Sign In was successful, authenticate with Firebase
GoogleSignInAccount account = result.getSignInAccount();
firebaseAuthWithGoogle(account);
} else {
// Google Sign In failed, update UI appropriately
// ...
Toast.makeText(this, "FAILED", Toast.LENGTH_SHORT).show();
}
}
}
private void firebaseAuthWithGoogle(GoogleSignInAccount account) {
Log.d(TAG, "firebaseAuthWithGoogle:" + account.getId());
AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());
Toast.makeText(MainActivity.this, "LOGGED IN", Toast.LENGTH_SHORT).show();
startActivity(new Intent(MainActivity.this, AccountActivity.class));
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
Log.w(TAG, "signInWithCredential", task.getException());
Toast.makeText(MainActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
// ...
}
});
}
}
//});
And this is my User.class file
package helloworld.firebase.com.helloworld;
public class User {
public String title, desc;
public User() {}
public User(String title, String desc) {
this.title = title;
this.desc = desc;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
The app runs perfectly but the RecyclerView adapter isn't getting attached. That is the only issue that I am facing right now. Would be great if someone can help out. Thanks in advance :)
Based on the android life cycle callbacks,
onStart()
gets called only afteronCreate()
. And in your code, you tried to attachfirebaseRecyclerAdapter
to adapter before it was initialised.If you wish to get rid from that annoying message, either you set empty adapter inside
onCreate()
or move all of your FirebaseRecyclerAdapter codes to onCreate and then set an adapter .Check solved topic here
You need to attach your adapter when you initialize your RecyclerView and attach LayoutManager, etc.