FirebaseUI-Android icon indicating copy to clipboard operation
FirebaseUI-Android copied to clipboard

Switching language of Firebase phone sign-in UI on Android

Open vijtheveg opened this issue 5 years ago • 4 comments

I am developing and Android native application that allows the user to choose the UI language in the first page. All other pages are then displayed in the chosen UI.

The third page of the app requires the user to sign-in using the Firebase phone auth UI (version com.google.firebase:firebase-auth:19.2.0). Unfortunately, the phone auth UI always seems to display in the phone / system language. In other words, if the language of the phone is English, the phone auth UI is always displayed in English. Even if the user has chosen Hindi as the preferred language in the first page, I couldn't find a way to instruct the Firebase phone auth UI to display in Hindi.

This issue is to request a feature to add a locale parameter to the the Firebase phone auth UI, so that the app can specify the language in which the phone auth UI is displayed. For more details, please see this post: https://groups.google.com/forum/#!topic/firebase-talk/Xfkk83y0FHw

The code for switching the locale of an activity is pretty straightforward (albeit non-intuitive). Essentially, in the base activity of all the phone auth UI activities, the locale of the configuration in the context attached to the activity needs to be changed by overriding attachBaseContext. A snippet of this code is shown below:


    // See https://proandroiddev.com/change-language-programmatically-at-runtime-on-android-5e6bc15c758
    @Override
    protected void attachBaseContext(Context newBase) {

        // getLocale() is some method that returns the locale chosen by the user for this activity
        Locale newLocale = getLocale();
        Locale.setDefault(newLocale);

        Resources resources = newBase.getResources();
        Configuration configuration = new Configuration(resources.getConfiguration());

        if (Build.VERSION.SDK_INT >= 17) {

            configuration.setLocale(newLocale);
            configuration.setLayoutDirection(newLocale);
            newBase = newBase.createConfigurationContext(configuration);
        } else {

            configuration.locale = newLocale;
            resources.updateConfiguration(configuration, resources.getDisplayMetrics());
        }

        super.attachBaseContext(newBase);
    }

    // See https://stackoverflow.com/questions/55265834/change-locale-not-work-after-migrate-to-androidx
    @Override
    public void applyOverrideConfiguration(Configuration overrideConfiguration) {

        if (overrideConfiguration != null) {

            int uiMode = overrideConfiguration.uiMode;
            overrideConfiguration.setTo(getBaseContext().getResources().getConfiguration());
            overrideConfiguration.uiMode = uiMode;
        }
        super.applyOverrideConfiguration(overrideConfiguration);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        // Do other stuff here

        resetTitle();
    }

    // See https://proandroiddev.com/change-language-programmatically-at-runtime-on-android-5e6bc15c758
    private void resetTitle() {

        // Required to correctly set the title after language change
        try {

            int label = getPackageManager().getActivityInfo(getComponentName(), GET_META_DATA).labelRes;
            if (label != 0)
                setTitle(label);
        } catch (PackageManager.NameNotFoundException e) {

            // Nothing much can be done - just log the exception
            logException(e);
        }
    }

vijtheveg avatar Feb 22 '20 16:02 vijtheveg

@vijtheveg thank you for all the details here!

samtstern avatar Feb 28 '20 00:02 samtstern

So I've thought about it some more and while I am sure this code works today, I'm not comfortable putting it into the library since these types of "hacks" often break with Android API upgrades and I don't fully understand it in the first place.

I am going to put this on the backlog, waiting for some Android library to help do this in a less hacky way. Thank you again for your research!

samtstern avatar Jul 21 '20 13:07 samtstern

Agreed with the sentiment about not putting hacky stuff in. Also agreed that the code I have suggested above is hacky (but there is no better way).

However,

This issue is to request a feature to add a locale parameter to the the Firebase phone auth UI

why not just let the caller specify a locale in that case? You will explicitly use this passed-in locale when you load resources and this approach won't work for a large app, but the Firebase auth UI on Android is pretty contained (just a couple of screens). It is not elegant, but it is not hacky and it may be a good compromise for solving a real customer problem :)

vijtheveg avatar Jul 21 '20 14:07 vijtheveg