firebase / firebase-tools

The Firebase Command Line Tools
MIT License
4.02k stars 938 forks source link

`firebase auth:export` doesn't include provider info for Apple Sign In #3401

Open nilsreichardt opened 3 years ago

nilsreichardt commented 3 years ago

[REQUIRED] Environment info

firebase-tools: 9.11.0

Platform: macOS (M1)

[REQUIRED] Test case

I can't provide a test case, because I would need to give you access to my Firebase project.

[REQUIRED] Steps to reproduce

  1. Set up a Firebase project
  2. Enable "Apple Sign In" for Firebase Auth
  3. Use Sign In with Apple with a user
  4. Run firebase auth:export auth_export.json
  5. Open auth_export.json

[REQUIRED] Expected behavior

I would expect that the provider info also be export like:

{
  "localId": "0YPO0atCUVaeP8gTIZVDn4oZxIZ2",
  "email": "myaccount@icloud.com",
  "emailVerified": true,
  "lastSignedInAt": "1621582693401",
  "createdAt": "1621582693401",
  "providerUserInfo": [
   {
      "providerId": "apple.com",
      "rawId": "rawId",
      "email": "myaccount@icloud.com",
      "displayName": "MyName",
    }
  ]
},

If you import this data, the user should have an Apple provider:

Screenshot 2021-05-25 at 00 02 00

[REQUIRED] Actual behavior

{
  "localId": "0YPO0atCUVaeP8gTIZVDn4oZxIZ2",
  "email": "myaccount@icloud.com",
  "emailVerified": true,
  "lastSignedInAt": "1621582693401",
  "createdAt": "1621582693401",
  "providerUserInfo": [] // <----- Why is this empty???
},

If you import this data, the use will not have a provider:

Screenshot 2021-05-25 at 00 00 07
hwo411 commented 3 years ago

The same happens with Google Play users. I believe it must be a bug in the called api:

https://developers.google.com/identity/toolkit/web/reference/relyingparty/downloadAccount

The workaround I'm considering is calling listUsers from admin-sdk, because it contains the providersUserInfo

Update: actually listUsers also calls this api (see: https://github.com/firebase/firebase-admin-node/blob/e7ab2f046843c23bb95b382c3896ca104c6d75f6/src/auth/auth.ts#L279), so the issue in the firebase-tools

hwo411 commented 3 years ago

I investigated the code and discovered that apple.com, gc.apple.com and playgames.google.com are missed there: https://github.com/firebase/firebase-tools/blob/66447909ab6f2defd04b257b48193c70d778c7ea/src/accountExporter.js#L30

Unfortunately, I don't know their ids and I'm not familiar with the other details of the tool to provide a PR. Hope that someone will fix it soon, for now I at least know how to add a workaround to our scripts.

hwo411 commented 3 years ago

In addition to that, importer should be extended with these providers too: https://github.com/firebase/firebase-tools/blob/66447909ab6f2defd04b257b48193c70d778c7ea/src/accountImporter.js#L31

I changed this locally and export and import successfully worked for me (still need to check whether the auth for play games and game center will work in the app).

stammy commented 2 years ago

+1 having this issue now

haydenbleasel commented 2 years ago

Made some progress on this locally. Cloned firebase-tools and made the following changes:

  1. in src/accountExporter, add "apple.com": 23 to the PROVIDER_ID_INDEX_MAP (I think you can just assign any number in increments of 4)
  2. in src/accountImporter, add "apple.com" to ALLOWED_PROVIDER_IDS
  3. in src/accountImporter, add _addProviderUserInfo(user, "apple.com", arr.slice(23, 27)); below the other _addProviderUserInfo calls (lines up with the ID index map from accountExporter)

It exports the providerUserInfo correctly i.e.

"providerUserInfo": [
    {
      "providerId": "apple.com",
      "rawId": "........",
      "email": "........."
    }
  ]

This caused a suppressed localId is missing error on import, so I had to swap out const user = validateUserJson(value); for const user = value in auth-import.ts. If you took some time, you could probably figure out why the validateUserJson function was returning {} instead of the user data.

Anyway, successfully imported all my apple-auth'ed users.

LorenzoInvernizzi commented 2 years ago

updates on when the fix will be published?

NeverwinterMoon commented 2 years ago

Having the same issue.

Not exported:

Exported:

lisajian commented 2 years ago

Hi, thanks for filing this issue! We are unable to promise any timeline for this, but if others also have this issue, adding a thumbs up on this issue can help us prioritize adding this to the roadmap.

(Googler-only internal tracking bug: b/240348641)

nilsreichardt commented 2 years ago

Hi @lisajian, it's great to see that this issue got some attention ❤️ However, it's for me unclear why the Firebase hasn't fixed this issue after 2 year (after adding Apple as new sign in provider). Exporting the Firebase Auth user is essential for every production app. How should you do your backups without exporting all users? Issues like this should be a red flag for every company for using Firebase in production because good backups are necessary for production apps.

stammy commented 2 years ago

Please fix this 🙏

lisajian commented 2 years ago

Totally understand your concern and we're working on triaging the issue internally. While this is getting addressed, please take a look at the other ways of exporting and importing users, e.g. Admin SDK's listUsers() for exporting and createUser() for importing, or you can hit the underlying endpoints directly by calling batchGet for exporting and batchCreate for importing. These will return up to date user info, including Apple as a sign in provider.

wreulicke commented 2 years ago

I encountered the same issue using a SAML provider. There is no information in providerUserInfo.

ViswanathB commented 1 year ago

Please fix this, hitting this issue for our firebase user export

ViswanathB commented 1 year ago

Please fix this, hitting this issue for our firebase user export

For anyone landing on this page, I worked around by using firebase_admin package in python and auth.list_users().iterate_all() but the password hashes are messed up. In cli export the password hashes are correct but in the sdk call all the /s are replaced with _s and +s are replaced with -s - I don't think this is expected. It saves lot of time if you know this. All capital and small alphabets stay the same. I am not how other characters are changed - is there a known correlation?

scionGhb commented 1 year ago

Made some progress on this locally. Cloned firebase-tools and made the following changes:

1. in `src/accountExporter`, add `"apple.com": 23` to the `PROVIDER_ID_INDEX_MAP` (I think you can just assign any number in increments of 4)

2. in `src/accountImporter`, add `"apple.com"` to `ALLOWED_PROVIDER_IDS`

3. in `src/accountImporter`, add `_addProviderUserInfo(user, "apple.com", arr.slice(23, 27));` below the other `_addProviderUserInfo` calls (lines up with the ID index map from `accountExporter`)

It exports the providerUserInfo correctly i.e.

"providerUserInfo": [
    {
      "providerId": "apple.com",
      "rawId": "........",
      "email": "........."
    }
  ]

This caused a suppressed localId is missing error on import, so I had to swap out const user = validateUserJson(value); for const user = value in auth-import.ts. If you took some time, you could probably figure out why the validateUserJson function was returning {} instead of the user data.

Anyway, successfully imported all my apple-auth'ed users.

I am facing this issue with microsoft providerId, but I am unable to find the src folder you mention, I am on macos, any help? thanks so much

scionGhb commented 1 year ago

Made some progress on this locally. Cloned firebase-tools and made the following changes:

1. in `src/accountExporter`, add `"apple.com": 23` to the `PROVIDER_ID_INDEX_MAP` (I think you can just assign any number in increments of 4)

2. in `src/accountImporter`, add `"apple.com"` to `ALLOWED_PROVIDER_IDS`

3. in `src/accountImporter`, add `_addProviderUserInfo(user, "apple.com", arr.slice(23, 27));` below the other `_addProviderUserInfo` calls (lines up with the ID index map from `accountExporter`)

It exports the providerUserInfo correctly i.e.

"providerUserInfo": [
    {
      "providerId": "apple.com",
      "rawId": "........",
      "email": "........."
    }
  ]

This caused a suppressed localId is missing error on import, so I had to swap out const user = validateUserJson(value); for const user = value in auth-import.ts. If you took some time, you could probably figure out why the validateUserJson function was returning {} instead of the user data.

Anyway, successfully imported all my apple-auth'ed users.

Great, Thanks. I did this for Microsoft accounts and it worked, the only thing was to find the files to edit, as I did not found the src folder, I had to use global search for the accountExporter.js file and the rest.

The export and import commands end of with and error, but json was exported correctly and imported as well on the new project.

tomas-carv-com commented 1 year ago

Any update on this ? I cant perform export/import of our accounts atm?!

brianaronowitzopen commented 1 year ago

Any updates here? on firebase tools version: 12.8.0, also getting "providerUserInfo": [] for all users when running firebase auth:export save_file.json --format=json

dev4jam commented 7 months ago

Made some progress on this locally. Cloned firebase-tools and made the following changes:

  1. in src/accountExporter, add "apple.com": 23 to the PROVIDER_ID_INDEX_MAP (I think you can just assign any number in increments of 4)
  2. in src/accountImporter, add "apple.com" to ALLOWED_PROVIDER_IDS
  3. in src/accountImporter, add _addProviderUserInfo(user, "apple.com", arr.slice(23, 27)); below the other _addProviderUserInfo calls (lines up with the ID index map from accountExporter)

It exports the providerUserInfo correctly i.e.

"providerUserInfo": [
    {
      "providerId": "apple.com",
      "rawId": "........",
      "email": "........."
    }
  ]

This caused a suppressed localId is missing error on import, so I had to swap out const user = validateUserJson(value); for const user = value in auth-import.ts. If you took some time, you could probably figure out why the validateUserJson function was returning {} instead of the user data.

Anyway, successfully imported all my apple-auth'ed users.

Appreciate your findings! Could you please let us know how to run this updated package?