update_user_meta not updating

In response to the extended question, i.e. Another question is[…]:

It is worth noting that WordPress’ plugin API does not persist between requests – that is to say, any functions associated with actions through WordPress’ add_action() are only associated for the duration of the script’s execution. Each subsequent request served by WordPress must once again bind functions with their proper actions (again, only for the duration of the request/script execution).

That in mind, you are binding the function showAdminMessagePwd() to the action admin_notices immediately before you execute a header-redirect, which should briefly prompt the client browser to terminate the request and start a new one at the indicated location. I may be misinterpreting the situation, but it seems reasonable that showAdminMessagePwd() is no longer bound to the action admin_notices when the script at http://example.com/wp-admin/profile.php executes as the add_action() call that binds it was executed in the context of an entirely separate request.

Binding the action within your functions.php file and outside of a function works fine because all of the code in a theme’s functions file is executed whenever the theme gets loaded (for the intents and purpose of this question, virtually always). Binding the action in a function will work flawlessly so long as the function is executed, and your function bound before the admin_notices action is executed.

One solution might be to attach the logic that determines whether or not to display to an action that executes on every request rather than wp_login, which only executes after a user has authenticated themselves. Such an implementation might look something along the lines of

function track_last_login( $login ) {
    $user = get_user_by( 'login', $login );
    $nLogins = (int) get_user_meta( $user->ID, 'Nlogins', true );

    update_user_meta( $user->ID, 'Nlogins', $nLogins + 1 );

    if( $nLogins === 1 )
        header("Location: http://example.com/wp-admin/profile.php");
}
add_action( 'wp_login', 'track_last_login' );

function admin_password_notice() {
    //If the user isn't logged in, or they are viewing pages outside of the dashboard, ignore them.
    if( !is_user_logged_in() || !is_admin() )
        return;

    $user = wp_get_current_user();
    $nLogins = (int) get_user_meta( $user->ID, 'Nlogins', true );

    if( $nLogins === 1 )
        add_action('admin_notices', 'showAdminMessagePwd');
}
add_action( 'after_theme_setup', 'admin_password_notice' );

Note that no calls to remove_action( 'admin_notices', 'showAdminMessagePwd' ) are necessary as, if $nLogins does not equal 1, the function is never bound to the action (no calls to add_action( 'admin_notices', 'showAdminMessagePwd' ) have been made), and thus no binding exists to be removed.

Also note that the function get_userdatabylogin() has been deprecated as of WordPress 3.3.