Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Last active January 28, 2024 19:16
Show Gist options
  • Save sunmeat/47e57b9788361c10d7a6bea216d851bb to your computer and use it in GitHub Desktop.
Save sunmeat/47e57b9788361c10d7a6bea216d851bb to your computer and use it in GitHub Desktop.
firebase chat with authentication android
AndroidManifest.xml:
проверить наличие
<activity android:name=".AuthActivity" />
==========================================================================================================================
AuthActivity.java:
package com.alex.firebase;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.View;
import android.widget.Toast;
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;
public class AuthActivity extends AppCompatActivity implements
GoogleApiClient.OnConnectionFailedListener, View.OnClickListener {
private static final int RC_SIGN_IN = 9001;
private SignInButton mAuthButton;
private FirebaseAuth mFirebaseAuth;
private GoogleApiClient mGoogleApiClient;
// Firebase instance variables
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auth);
mAuthButton = findViewById(R.id.auth_button);
mAuthButton.setOnClickListener(this);
mFirebaseAuth = FirebaseAuth.getInstance();
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.auth_button:
authorize();
break;
}
}
private void authorize() {
Intent authorizeIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(authorizeIntent, RC_SIGN_IN);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
GoogleSignInAccount account = result.getSignInAccount();
firebaseAuthWithGoogle(account);
} else {
// Google Sign In failed
}
}
}
private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
mFirebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
// 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()) {
Toast.makeText(AuthActivity.this, "authentication failed!",
Toast.LENGTH_SHORT).show();
} else {
startActivity(new Intent(AuthActivity.this, MainActivity.class));
finish();
}
}
});
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Toast.makeText(this, "connection failed!", Toast.LENGTH_SHORT).show();
}
}
==========================================================================================================================
activity_auth.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sign_in_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="40dp"
android:gravity="center"
android:text="Авторизуйтесь, пожалуйста"
android:textSize="30sp"
android:textStyle="bold" />
<com.google.android.gms.common.SignInButton
android:id="@+id/auth_button"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:visibility="visible" />
</FrameLayout>
==========================================================================================================================
menu / main_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/sign_out_menu"
android:title="Sign Out"
app:showAsAction="never" />
</menu>
==========================================================================================================================
MainActivity.java: (можно менять код целиком)
/*
что было добавлено:
1) активити теперь реализует интерфейс GoogleApiClient.OnConnectionFailedListener, требующий метод
public void onConnectionFailed(@NonNull ConnectionResult connectionResult);
2) сущности для работы с авторизацией
private GoogleApiClient mGoogleApiClient;
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirechatUser;
3) их инициализация в onCreate
4) работа с меню для разлогинивания в методе
public boolean onOptionsItemSelected(MenuItem item);
*/
package com.alex.firebase;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
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.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.FirebaseDatabase;
import de.hdodenhof.circleimageview.CircleImageView;
import com.bumptech.glide.Glide;
public class MainActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirechatUser;
private DatabaseReference db;
private FirebaseRecyclerAdapter<ChatMessage, MyViewHolder> fireAdapter;
private RecyclerView rv;
private LinearLayoutManager lm;
private ProgressBar progress;
String mPhotoUrl;
private EditText edit;
public static final String DEFAULT_NAME = "Alex";
private String userName;
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView msgTextView;
TextView userTextView;
CircleImageView userImageView;
public MyViewHolder(View v) {
super(v);
msgTextView = itemView.findViewById(R.id.msgTextView);
userTextView = itemView.findViewById(R.id.userTextView);
userImageView = itemView.findViewById(R.id.userImageView);
}
}
@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);
userName = DEFAULT_NAME;
startActivity(new Intent(this, AuthActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress = findViewById(R.id.progressBar);
rv = findViewById(R.id.messageRecyclerView);
lm = new LinearLayoutManager(this);
lm.setStackFromEnd(true);
rv.setLayoutManager(lm);
userName = DEFAULT_NAME;
edit = findViewById(R.id.msgEditText);
// https://stackoverflow.com/questions/42355796/firebase-google-sign-in-will-not-work-android !!!
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API)
.build();
mFirebaseAuth = FirebaseAuth.getInstance();
mFirechatUser = mFirebaseAuth.getCurrentUser();
if (mFirechatUser == null) {
startActivity(new Intent(this, AuthActivity.class));
finish();
return;
} else {
userName = mFirechatUser.getDisplayName();
if (mFirechatUser.getPhotoUrl() != null) {
mPhotoUrl = mFirechatUser.getPhotoUrl().toString();
}
}
db = FirebaseDatabase.getInstance().getReference();
fireAdapter = new FirebaseRecyclerAdapter<ChatMessage, MyViewHolder>(
ChatMessage.class,
R.layout.chat_message,
MyViewHolder.class,
db.child("messages")) {
@Override
protected void populateViewHolder(MyViewHolder viewHolder,
ChatMessage friendlyMessage, int position) {
progress.setVisibility(ProgressBar.INVISIBLE);
viewHolder.msgTextView.setText(friendlyMessage.getText());
viewHolder.userTextView.setText(friendlyMessage.getName());
if (friendlyMessage.getPhotoUrl() == null) {
viewHolder.userImageView
.setImageDrawable(ContextCompat
.getDrawable(MainActivity.this,
R.drawable.ic_account_circle_black_36dp));
} else {
Glide.with(MainActivity.this)
.load(friendlyMessage.getPhotoUrl())
.into(viewHolder.userImageView);
}
}
};
fireAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int friendlyMessageCount = fireAdapter.getItemCount();
int lastVisiblePosition =
lm.findLastCompletelyVisibleItemPosition();
if (lastVisiblePosition == -1 ||
(positionStart >= (friendlyMessageCount - 1) &&
lastVisiblePosition == (positionStart - 1))) {
rv.scrollToPosition(positionStart);
}
}
});
rv.setLayoutManager(lm);
rv.setAdapter(fireAdapter);
Button mSendButton = findViewById(R.id.sendButton);
mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ChatMessage friendlyMessage = new
ChatMessage(edit.getText().toString(), userName, mPhotoUrl);
db.child("messages").push().setValue(friendlyMessage);
edit.setText("");
}
});
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Toast.makeText(this, "connection failed (MainActivity)", Toast.LENGTH_SHORT).show();
}
}
==========================================================================================================================
build.gradle (Module:app):
...
implementation 'com.google.firebase:firebase-auth:16.0.2'
implementation 'com.google.android.gms:play-services-auth:15.0.1'
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment