在开始解释我的问题之前,我将向您展示我的错误的完整图像。
我尽力找到解决方案以及发生此错误的原因。
我担心你们会认为我的问题与那些问题是一样的,但我认为存在一些差异,所以我真的希望你们能够阅读我的问题。
首先,我已经按照Google的官方聊天应用教程进行了操作。 (this)
我刚刚复制了源代码,但第8章(发送消息)发生了错误。当我用文本发送消息时没有问题,但是当我从本地存储器发送带有图像文件的消息时出现了问题。我刚刚找到了消息来源'在google firebase中,这种类型的StorageException通常是由于StorageReference引用错误引起的。所以我查看了有关StorageReference的源代码。但我无法理解这个答案,我也找不到任何问题。
其次,我向您展示了有关错误消息的更多详细信息,并且我将向您展示MainActivity的完整源代码。
package com.google.firebase.codelab.friendlychat;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.InputFilter;
import android.text.Layout;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.firebase.ui.database.SnapshotParser;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.appinvite.AppInvite;
import com.google.android.gms.appinvite.AppInviteInvitation;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.crash.FirebaseCrash;
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.remoteconfig.FirebaseRemoteConfig;
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings;
import com.google.firebase.appindexing.Action;
import com.google.firebase.appindexing.FirebaseAppIndex;
import com.google.firebase.appindexing.FirebaseUserActions;
import com.google.firebase.appindexing.Indexable;
import com.google.firebase.appindexing.builders.Indexables;
import com.google.firebase.appindexing.builders.PersonBuilder;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.util.HashMap;
import java.util.Map;
import de.hdodenhof.circleimageview.CircleImageView;
public class MainActivity extends AppCompatActivity
implements GoogleApiClient.OnConnectionFailedListener {
public static class MessageViewHolder extends RecyclerView.ViewHolder {
TextView messageTextView;
ImageView messageImageView;
TextView messengerTextView;
CircleImageView messengerImageView;
public MessageViewHolder(View v) {
super(v);
messageTextView = (TextView) itemView.findViewById(R.id.messageTextView);
messageImageView = (ImageView) itemView.findViewById(R.id.messageImageView);
messengerTextView = (TextView) itemView.findViewById(R.id.messengerTextView);
messengerImageView = (CircleImageView) itemView.findViewById(R.id.messengerImageView);
}
public void bind(FriendlyMessage friendlyMessage){
messageTextView.setText(friendlyMessage.getText());
messageTextView.setVisibility(View.VISIBLE);
messageImageView.setVisibility(View.GONE);
}
}
private static final String TAG = "MainActivity";
public static final String MESSAGES_CHILD = "messages";
private static final int REQUEST_INVITE = 1;
private static final int REQUEST_IMAGE = 2;
private static final String LOADING_IMAGE_URL = "https://www.google.com/images/spin-32.gif";
public static final int DEFAULT_MSG_LENGTH_LIMIT = 10;
public static final String ANONYMOUS = "anonymous";
private static final String MESSAGE_SENT_EVENT = "message_sent";
private String mUsername;
private String mPhotoUrl;
private SharedPreferences mSharedPreferences;
private GoogleApiClient mGoogleApiClient;
private static final String MESSAGE_URL = "http://friendlychat.firebase.google.com/message/";
private Button mSendButton;
private RecyclerView mMessageRecyclerView;
private LinearLayoutManager mLinearLayoutManager;
private ProgressBar mProgressBar;
private EditText mMessageEditText;
private ImageView mAddMessageImageView;
// Firebase instance variables
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirebaseUser;
private DatabaseReference mFirebaseDatabaseReference;
private FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder> mFirebaseAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// Set default username is anonymous.
mUsername = ANONYMOUS;
// Initialize Firebase Auth
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = mFirebaseAuth.getCurrentUser();
if(mFirebaseUser == null){
// Not signed in, launch the Sign In activity
startActivity(new Intent(this, SignInActivity.class));
finish();
return;
}
else {
mUsername = mFirebaseUser.getDisplayName();
if(mFirebaseUser.getPhotoUrl() != null){
mPhotoUrl = mFirebaseUser.getPhotoUrl().toString();
}
}
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API)
.build();
// Initialize ProgressBar and RecyclerView.
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mMessageRecyclerView = (RecyclerView) findViewById(R.id.messageRecyclerView);
mLinearLayoutManager = new LinearLayoutManager(this);
mLinearLayoutManager.setStackFromEnd(true);
// mLinearLayoutManager.setReverseLayout(true);
mMessageRecyclerView.setLayoutManager(mLinearLayoutManager);
mProgressBar.setVisibility(ProgressBar.INVISIBLE);
mMessageEditText = (EditText) findViewById(R.id.messageEditText);
mMessageEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(mSharedPreferences
.getInt(CodelabPreferences.FRIENDLY_MSG_LENGTH, DEFAULT_MSG_LENGTH_LIMIT))});
mMessageEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().trim().length() > 0) {
mSendButton.setEnabled(true);
} else {
mSendButton.setEnabled(false);
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
mSendButton = (Button) findViewById(R.id.sendButton);
mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Send messages on click.
FriendlyMessage friendlyMessage = new FriendlyMessage(mMessageEditText.getText().toString(),
mUsername,
mPhotoUrl,
null);
mFirebaseDatabaseReference.child(MESSAGES_CHILD)
.push().setValue(friendlyMessage);
mMessageEditText.setText("");
}
});
mAddMessageImageView = (ImageView) findViewById(R.id.addMessageImageView);
mAddMessageImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Select image for image message on click.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_IMAGE);
}
});
// New child entries
mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
SnapshotParser<FriendlyMessage> parser = new SnapshotParser<FriendlyMessage>() {
@Override
public FriendlyMessage parseSnapshot(DataSnapshot dataSnapshot) {
FriendlyMessage friendlyMessage = dataSnapshot.getValue(FriendlyMessage.class);
if(friendlyMessage != null){
friendlyMessage.setId(dataSnapshot.getKey());
}
return friendlyMessage;
}
};
DatabaseReference messageRef = mFirebaseDatabaseReference.child(MESSAGES_CHILD);
FirebaseRecyclerOptions<FriendlyMessage> options =
new FirebaseRecyclerOptions.Builder<FriendlyMessage>()
.setQuery(messageRef, parser)
.build();
mFirebaseAdapter = new FirebaseRecyclerAdapter<FriendlyMessage, MessageViewHolder>(options) {
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
return new MessageViewHolder(inflater.inflate(R.layout.item_message, parent, false));
}
@Override
protected void onBindViewHolder(final MessageViewHolder holder, int position, FriendlyMessage friendlyMessage) {
mProgressBar.setVisibility(View.INVISIBLE);
if(friendlyMessage.getText() != null){
holder.bind(friendlyMessage);
}
else {
String imageUrl = friendlyMessage.getImageUrl();
if(imageUrl.startsWith("gs://")) {
StorageReference storageReference = FirebaseStorage.getInstance()
.getReferenceFromUrl(imageUrl);
storageReference.getDownloadUrl().addOnCompleteListener(
new OnCompleteListener<Uri>() {
@Override
public void onComplete(@NonNull Task<Uri> task) {
if(task.isSuccessful()){
String downloadUrl= task.getResult().toString();
Glide.with(holder.messageImageView.getContext())
.load(downloadUrl)
.into(holder.messageImageView);
}
else {
Log.w(TAG, "Getting download url was not seccessful.",
task.getException());
}
}
}
);
}
else {
Glide.with(holder.messageImageView.getContext())
.load(friendlyMessage.getImageUrl())
.into(holder.messageImageView);
}
holder.messageImageView.setVisibility(ImageView.VISIBLE);
holder.messageTextView.setVisibility(TextView.GONE);
}
holder.messengerTextView.setText(friendlyMessage.getName());
if(friendlyMessage.getPhotoUrl() == null){
holder.messengerImageView.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,
R.drawable.ic_account_circle_black_36dp));
}
else {
Glide.with(MainActivity.this)
.load(friendlyMessage.getPhotoUrl())
.into(holder.messengerImageView);
}
}
};
mFirebaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = mFirebaseAdapter.getItemCount();
int lastVisiblePosotion =
mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
if(lastVisiblePosotion == -1 ||
(positionStart >= (friendlyMessageCount - 1) && lastVisiblePosotion == (positionStart - 1))){
mMessageRecyclerView.scrollToPosition(positionStart);
}
}
});
mMessageRecyclerView.setAdapter(mFirebaseAdapter);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: requestCode=" + requestCode + ", resultCode=" + resultCode);
if (requestCode == REQUEST_IMAGE) {
if (resultCode == RESULT_OK) {
if (data != null) {
final Uri uri = data.getData();
Log.d(TAG, "Uri: " + uri.toString());
FriendlyMessage tempMessage = new FriendlyMessage(null, mUsername, mPhotoUrl,
LOADING_IMAGE_URL);
mFirebaseDatabaseReference.child(MESSAGES_CHILD).push()
.setValue(tempMessage, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError,
DatabaseReference databaseReference) {
if (databaseError == null) {
String key = databaseReference.getKey();
StorageReference storageReference =
FirebaseStorage.getInstance()
.getReference(mFirebaseUser.getUid())
.child(key)
.child( uri.getLastPathSegment());
putImageInStorage(storageReference, uri, key);
} else {
Log.w(TAG, "Unable to write message to database.",
databaseError.toException());
}
}
});
}
}
}
}
private void putImageInStorage(StorageReference storageReference, Uri uri, final String key) {
storageReference.putFile(uri).addOnCompleteListener(MainActivity.this,
new OnCompleteListener<UploadTask.TaskSnapshot>() {
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
FriendlyMessage friendlyMessage =
new FriendlyMessage(null, mUsername, mPhotoUrl,
task.getResult().getMetadata().getDownloadUrl()
.toString());
mFirebaseDatabaseReference.child(MESSAGES_CHILD).child(key)
.setValue(friendlyMessage);
} else {
Log.w(TAG, "Image upload task was not successful.",
task.getException());
}
}
});
}
@Override
public void onStart() {
super.onStart();
// Check if user is signed in.
// TODO: Add code to check if user is signed in.
}
@Override
public void onPause() {
mFirebaseAdapter.stopListening();
super.onPause();
}
@Override
public void onResume() {
super.onResume();
mFirebaseAdapter.startListening();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.sign_out_menu:
mFirebaseAuth.signOut();
Auth.GoogleSignInApi.signOut(mGoogleApiClient);
mUsername = ANONYMOUS;
startActivity(new Intent(this, SignInActivity.class));
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
// An unresolvable error has occurred and Google APIs (including Sign-In) will not
// be available.
Log.d(TAG, "onConnectionFailed:" + connectionResult);
Toast.makeText(this, "Google Play Services error.", Toast.LENGTH_SHORT).show();
}
}
我认为我对Firebase身份验证和安装或Google Play服务版本没有任何问题。
感谢您阅读我的问题。