Skip to content
28 changes: 28 additions & 0 deletions app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import android.widget.RadioButton;
import android.widget.TextView;

import com.firebase.ui.auth.AuthMethodPickerLayout;
import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.ErrorCodes;
Expand All @@ -48,6 +49,7 @@
import com.google.firebase.auth.FirebaseAuth;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import butterknife.BindView;
Expand Down Expand Up @@ -258,6 +260,32 @@ public Intent buildSignInIntent(@Nullable String link) {
return builder.build();
}

@OnClick(R.id.customised_sign_in)
public void signInCustomLayout() {
AuthMethodPickerLayout customLayout = new AuthMethodPickerLayout
.Builder(R.layout.auth_method_picker_custom_layout)
.setupGoogleButtonId(R.id.custom_google_signin_button)
.setupEmailButtonId(R.id.custom_email_signin_clickable_text)
.build();

//For now we only test Google and Email
List<IdpConfig> availableProviders = Arrays.asList(
new AuthUI.IdpConfig.GoogleBuilder()
.setScopes(getGoogleScopes())
.build(),
new IdpConfig.EmailBuilder()
.setRequireName(mRequireName.isChecked())
.setAllowNewAccounts(mAllowNewEmailAccounts.isChecked())
.build());

startActivityForResult(
AuthUI.getInstance().createSignInIntentBuilder()
.setAvailableProviders(availableProviders)
.setAuthMethodPickerLayout(customLayout)
.build(),
RC_SIGN_IN);
}

@OnClick(R.id.sign_in_silent)
public void silentSignIn() {
AuthUI.getInstance().silentSignIn(this, getSelectedProviders())
Expand Down
57 changes: 57 additions & 0 deletions app/src/main/res/layout/auth_method_picker_custom_layout.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" android:gravity="center_horizontal">

<TextView
android:text="@string/launch_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textAlignment="center"
android:layout_margin="24dp"
android:layout_marginBottom="0dp"/>

<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textSize="16sp"
android:layout_margin="16dp"
android:layout_marginBottom="32dp"
android:text="@string/custom_auth_picker_hint"/>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal">

<Button
android:id="@+id/custom_google_signin_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/providers_google"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginTop="8dp">

<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/custom_auth_use_email"/>

<TextView android:id="@+id/custom_email_signin_clickable_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/providers_email"
android:clickable="true"
android:focusable="true"
android:textStyle="bold"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"/>
</LinearLayout>
</LinearLayout>
10 changes: 10 additions & 0 deletions app/src/main/res/layout/auth_ui_layout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@
android:layout_marginBottom="16dp"
android:text="@string/sign_in_silent" />

<Button
android:id="@+id/customised_sign_in"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_gravity="center"
android:layout_marginBottom="16dp"
android:text="@string/custom_auth_picker_start"/>

<TextView
style="@style/Base.TextAppearance.AppCompat.Subhead"
android:layout_width="wrap_content"
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@
<string name="idp_token">IDP Token</string>
<string name="idp_secret">IDP Secret</string>

<!-- Auth UI - Custom AuthMethodPickerLayout -->
<string name="custom_auth_picker_start">Start with Custom Layout</string>
<string name="custom_auth_picker_hint">You can use customised layout like this to improve your user experience!
</string>
<string name="custom_auth_use_email">Or you can also sign in by using</string>


<!-- Storage -->
<string name="choose_image">Choose Image</string>
<string name="upload">Upload</string>
Expand Down
132 changes: 132 additions & 0 deletions auth/src/main/java/com/firebase/ui/auth/AuthMethodPickerLayout.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package com.firebase.ui.auth;

import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import com.google.firebase.auth.*;

import java.util.*;

/**
* Layout model to help customizing the AuthPicker
*/
public class AuthMethodPickerLayout implements Parcelable {

@LayoutRes
private int mainLayout;

/**
* PROVIDER_ID -> IdRes of the Button
*/
private Map<String, Integer> providersButton;

private AuthMethodPickerLayout() {
}

private AuthMethodPickerLayout(@NonNull Parcel in) {
this.mainLayout = in.readInt();
Bundle buttonsBundle = in.readBundle(getClass().getClassLoader());
this.providersButton = new HashMap<>();

for (String key : buttonsBundle.keySet()) {
this.providersButton.put(key, buttonsBundle.getInt(key));
}
}

@LayoutRes
public int getMainLayout() {
return mainLayout;
}

public Map<String, Integer> getProvidersButton() {
return providersButton;
}

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(mainLayout);

Bundle bundle = new Bundle();
for (String key : providersButton.keySet()) {
bundle.putInt(key, providersButton.get(key));
}
parcel.writeBundle(bundle);
}

public static final Creator<AuthMethodPickerLayout> CREATOR = new Creator<AuthMethodPickerLayout>() {

@Override
public AuthMethodPickerLayout createFromParcel(Parcel in) {
return new AuthMethodPickerLayout(in);
}

@Override
public AuthMethodPickerLayout[] newArray(int size) {
return new AuthMethodPickerLayout[size];
}
};

/**
* Builder for AuthMethodPickerLayout
*/
public static class Builder {

private Map<String, Integer> providersMapping;
private AuthMethodPickerLayout instance;

public Builder(@LayoutRes int mainLayout) {
instance = new AuthMethodPickerLayout();
instance.mainLayout = mainLayout;
providersMapping = new HashMap<>();
}

public AuthMethodPickerLayout.Builder setupGoogleButtonId(@IdRes int googleBtn) {
providersMapping.put(GoogleAuthProvider.PROVIDER_ID, googleBtn);
return this;
}

public AuthMethodPickerLayout.Builder setupFacebookButtonId(@IdRes int facebookBtn) {
providersMapping.put(FacebookAuthProvider.PROVIDER_ID, facebookBtn);
return this;
}

public AuthMethodPickerLayout.Builder setupTwitterButtonId(@IdRes int twitterBtn) {
providersMapping.put(TwitterAuthProvider.PROVIDER_ID, twitterBtn);
return this;
}

public AuthMethodPickerLayout.Builder setupEmailButtonId(@IdRes int emailButton) {
providersMapping.put(EmailAuthProvider.PROVIDER_ID, emailButton);
return this;
}

public AuthMethodPickerLayout.Builder setupPhoneButtonId(@IdRes int phoneButton) {
providersMapping.put(PhoneAuthProvider.PROVIDER_ID, phoneButton);
return this;
}

public AuthMethodPickerLayout.Builder setupAnonymousButtonId(@IdRes int anonymousButton) {
providersMapping.put(AuthUI.ANONYMOUS_PROVIDER, anonymousButton);
return this;
}

public AuthMethodPickerLayout build() {
//Validating the button set
for (String key : providersMapping.keySet()) {
if (!AuthUI.SUPPORTED_PROVIDERS.contains(key)) {
throw new IllegalArgumentException("Unknown provider: " + key);
}
}
instance.providersButton = providersMapping;
return instance;
}
}
}
10 changes: 9 additions & 1 deletion auth/src/main/java/com/firebase/ui/auth/AuthUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,7 @@ private abstract class AuthIntentBuilder<T extends AuthIntentBuilder> {
boolean mAlwaysShowProviderChoice = false;
boolean mEnableCredentials = true;
boolean mEnableHints = true;
AuthMethodPickerLayout mAuthMethodPickerLayout = null;

/**
* Specifies the theme to use for the application flow. If no theme is specified, a
Expand Down Expand Up @@ -1230,6 +1231,12 @@ public T setIsSmartLockEnabled(boolean enableCredentials, boolean enableHints) {
return (T) this;
}

@NonNull
public T setAuthMethodPickerLayout(@NonNull AuthMethodPickerLayout authMethodPickerLayout) {
mAuthMethodPickerLayout = authMethodPickerLayout;
return (T) this;
}

/**
* Forces the sign-in method choice screen to always show, even if there is only
* a single provider configured.
Expand Down Expand Up @@ -1301,7 +1308,8 @@ protected FlowParameters getFlowParams() {
mEnableHints,
mEnableAnonymousUpgrade,
mAlwaysShowProviderChoice,
mEmailLink);
mEmailLink,
mAuthMethodPickerLayout);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import android.support.annotation.StyleRes;
import android.text.TextUtils;

import com.firebase.ui.auth.AuthMethodPickerLayout;
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.util.ExtraConstants;
import com.firebase.ui.auth.util.Preconditions;
Expand Down Expand Up @@ -51,6 +52,7 @@ public FlowParameters createFromParcel(Parcel in) {
boolean enableAnonymousUpgrade = in.readInt() != 0;
boolean alwaysShowProviderChoice = in.readInt() != 0;
String emailLink = in.readString();
AuthMethodPickerLayout customLayout = in.readParcelable(AuthMethodPickerLayout.class.getClassLoader());

return new FlowParameters(
appName,
Expand All @@ -63,7 +65,8 @@ public FlowParameters createFromParcel(Parcel in) {
enableHints,
enableAnonymousUpgrade,
alwaysShowProviderChoice,
emailLink);
emailLink,
customLayout);
}

@Override
Expand Down Expand Up @@ -98,6 +101,9 @@ public FlowParameters[] newArray(int size) {
public final boolean enableAnonymousUpgrade;
public final boolean alwaysShowProviderChoice;

@Nullable
public final AuthMethodPickerLayout authMethodPickerLayout;

public FlowParameters(
@NonNull String appName,
@NonNull List<IdpConfig> providers,
Expand All @@ -109,7 +115,8 @@ public FlowParameters(
boolean enableHints,
boolean enableAnonymousUpgrade,
boolean alwaysShowProviderChoice,
@Nullable String emailLink) {
@Nullable String emailLink,
@Nullable AuthMethodPickerLayout authMethodPickerLayout) {
this.appName = Preconditions.checkNotNull(appName, "appName cannot be null");
this.providers = Collections.unmodifiableList(
Preconditions.checkNotNull(providers, "providers cannot be null"));
Expand All @@ -122,6 +129,7 @@ public FlowParameters(
this.enableAnonymousUpgrade = enableAnonymousUpgrade;
this.alwaysShowProviderChoice = alwaysShowProviderChoice;
this.emailLink = emailLink;
this.authMethodPickerLayout = authMethodPickerLayout;
}

/**
Expand All @@ -144,6 +152,7 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(enableAnonymousUpgrade ? 1 : 0);
dest.writeInt(alwaysShowProviderChoice ? 1 : 0);
dest.writeString(emailLink);
dest.writeParcelable(authMethodPickerLayout, flags);
}

@Override
Expand Down
Loading