Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(authentication): expose providerData and metadata property #432

Merged
merged 6 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/happy-cows-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@capacitor-firebase/authentication': minor
---

feat: expose `providerData` and `metadata` property
44 changes: 33 additions & 11 deletions packages/authentication/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1513,17 +1513,39 @@ Remove all listeners for this plugin.

#### User

| Prop | Type | Since |
| ------------------- | --------------------------- | ----- |
| **`displayName`** | <code>string \| null</code> | 0.1.0 |
| **`email`** | <code>string \| null</code> | 0.1.0 |
| **`emailVerified`** | <code>boolean</code> | 0.1.0 |
| **`isAnonymous`** | <code>boolean</code> | 0.1.0 |
| **`phoneNumber`** | <code>string \| null</code> | 0.1.0 |
| **`photoUrl`** | <code>string \| null</code> | 0.1.0 |
| **`providerId`** | <code>string</code> | 0.1.0 |
| **`tenantId`** | <code>string \| null</code> | 0.1.0 |
| **`uid`** | <code>string</code> | 0.1.0 |
| Prop | Type | Description | Since |
| ------------------- | ----------------------------------------------------- | -------------------------------------------------------------------- | ----- |
| **`displayName`** | <code>string \| null</code> | | 0.1.0 |
| **`email`** | <code>string \| null</code> | | 0.1.0 |
| **`emailVerified`** | <code>boolean</code> | | 0.1.0 |
| **`isAnonymous`** | <code>boolean</code> | | 0.1.0 |
| **`metadata`** | <code><a href="#usermetadata">UserMetadata</a></code> | The user's metadata. | 5.2.0 |
| **`phoneNumber`** | <code>string \| null</code> | | 0.1.0 |
| **`photoUrl`** | <code>string \| null</code> | | 0.1.0 |
| **`providerData`** | <code>UserInfo[]</code> | Additional per provider such as displayName and profile information. | 5.2.0 |
| **`providerId`** | <code>string</code> | | 0.1.0 |
| **`tenantId`** | <code>string \| null</code> | | 0.1.0 |
| **`uid`** | <code>string</code> | | 0.1.0 |


#### UserMetadata

| Prop | Type | Description | Since |
| -------------------- | ------------------- | ------------------------------------------------------------- | ----- |
| **`creationTime`** | <code>number</code> | Time the user was created in milliseconds since the epoch. | 5.2.0 |
| **`lastSignInTime`** | <code>number</code> | Time the user last signed in in milliseconds since the epoch. | 5.2.0 |


#### UserInfo

| Prop | Type | Description | Since |
| ----------------- | --------------------------- | ----------------------------------------------------------------------------------------- | ----- |
| **`displayName`** | <code>string \| null</code> | The display name of the user. | 5.2.0 |
| **`email`** | <code>string \| null</code> | The email of the user. | 5.2.0 |
| **`phoneNumber`** | <code>string \| null</code> | The phone number normalized based on the E.164 standard (e.g. +16505550101) for the user. | 5.2.0 |
| **`photoUrl`** | <code>string \| null</code> | The profile photo URL of the user. | 5.2.0 |
| **`providerId`** | <code>string</code> | The provider used to authenticate the user. | 5.2.0 |
| **`uid`** | <code>string</code> | The user's unique ID. | 5.2.0 |


#### AuthCredential
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package io.capawesome.capacitorjs.plugins.firebase.authentication;

import androidx.annotation.Nullable;
import com.getcapacitor.JSArray;
import com.getcapacitor.JSObject;
import com.google.firebase.auth.AdditionalUserInfo;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.FirebaseAuthException;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.FirebaseUserMetadata;
import com.google.firebase.auth.OAuthCredential;
import com.google.firebase.auth.UserInfo;
import java.util.List;
import java.util.Map;
import org.json.JSONObject;

public class FirebaseAuthenticationHelper {

Expand Down Expand Up @@ -65,8 +70,10 @@ public static JSObject createUserResult(@Nullable FirebaseUser user) {
result.put("email", user.getEmail());
result.put("emailVerified", user.isEmailVerified());
result.put("isAnonymous", user.isAnonymous());
result.put("metadata", FirebaseAuthenticationHelper.createUserMetadataResult(user.getMetadata()));
result.put("phoneNumber", user.getPhoneNumber());
result.put("photoUrl", user.getPhotoUrl());
result.put("providerData", FirebaseAuthenticationHelper.createUserProviderDataResult(user.getProviderData()));
result.put("providerId", user.getProviderId());
result.put("tenantId", user.getTenantId());
result.put("uid", user.getUid());
Expand Down Expand Up @@ -136,6 +143,31 @@ public static JSObject createAdditionalUserInfoResult(@Nullable AdditionalUserIn
return result;
}

private static JSObject createUserMetadataResult(@Nullable FirebaseUserMetadata metadata) {
JSObject result = new JSObject();
if (metadata == null) {
return result;
}
result.put("creationTime", metadata.getCreationTimestamp());
result.put("lastSignInTime", metadata.getLastSignInTimestamp());
return result;
}

private static JSArray createUserProviderDataResult(List<? extends UserInfo> providerData) {
JSArray result = new JSArray();
for (UserInfo userInfo : providerData) {
JSObject userInfoResult = new JSObject();
userInfoResult.put("displayName", (userInfo.getDisplayName() == null ? JSONObject.NULL : userInfo.getDisplayName()));
userInfoResult.put("email", (userInfo.getEmail() == null ? JSONObject.NULL : userInfo.getEmail()));
userInfoResult.put("phoneNumber", (userInfo.getPhoneNumber() == null ? JSONObject.NULL : userInfo.getPhoneNumber()));
userInfoResult.put("photoUrl", (userInfo.getPhotoUrl() == null ? JSONObject.NULL : userInfo.getPhotoUrl()));
userInfoResult.put("providerId", userInfo.getProviderId());
userInfoResult.put("uid", userInfo.getUid());
result.put(userInfoResult);
}
return result;
}

private static String snakeToKebabCase(String snakeCase) {
return snakeCase.replaceAll("_+", "-").toLowerCase();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ public class FirebaseAuthenticationHelper {
result["email"] = user.email
result["emailVerified"] = user.isEmailVerified
result["isAnonymous"] = user.isAnonymous
result["metadata"] = self.createUserMetadataResult(user.metadata)
result["phoneNumber"] = user.phoneNumber
result["photoUrl"] = user.photoURL?.absoluteString
result["providerData"] = self.createUserProviderDataResult(user.providerData)
result["providerId"] = user.providerID
result["tenantId"] = user.tenantID
result["uid"] = user.uid
Expand Down Expand Up @@ -125,6 +127,32 @@ public class FirebaseAuthenticationHelper {
return result
}

private static func createUserMetadataResult(_ metadata: UserMetadata) -> JSObject {
var result = JSObject()
if let creationDate = metadata.creationDate?.timeIntervalSince1970 {
result["creationTime"] = creationDate * 1000
}
if let lastSignInDate = metadata.lastSignInDate?.timeIntervalSince1970 {
result["lastSignInTime"] = lastSignInDate * 1000
}
return result
}

private static func createUserProviderDataResult(_ providerData: [UserInfo]) -> JSArray {
var result = JSArray()
for userInfo in providerData {
var userInfoResult = JSObject()
userInfoResult["displayName"] = userInfo.displayName
userInfoResult["email"] = userInfo.email
userInfoResult["phoneNumber"] = userInfo.phoneNumber
userInfoResult["photoUrl"] = userInfo.photoURL?.absoluteString
userInfoResult["providerId"] = userInfo.providerID
userInfoResult["uid"] = userInfo.uid
result.append(userInfoResult)
}
return result
}

private static func convertErrorCodeToString(errorCode: Int) -> String? {
let errorCodes: [Int: String] = [
AuthErrorCode.invalidCustomToken.rawValue: "invalid-custom-token",
Expand Down
77 changes: 77 additions & 0 deletions packages/authentication/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,7 @@ export interface UseEmulatorOptions {

/**
* @since 0.1.0
* @see https://firebase.google.com/docs/reference/js/auth.user
*/
export interface User {
/**
Expand All @@ -1062,6 +1063,12 @@ export interface User {
* @since 0.1.0
*/
isAnonymous: boolean;
/**
* The user's metadata.
*
* @since 5.2.0
*/
metadata: UserMetadata;
/**
* @since 0.1.0
*/
Expand All @@ -1070,6 +1077,12 @@ export interface User {
* @since 0.1.0
*/
photoUrl: string | null;
/**
* Additional per provider such as displayName and profile information.
*
* @since 5.2.0
*/
providerData: UserInfo[];
/**
* @since 0.1.0
*/
Expand All @@ -1084,6 +1097,70 @@ export interface User {
uid: string;
}

/**
* @since 5.2.0
* @see https://firebase.google.com/docs/reference/js/auth.userinfo
*/
export interface UserInfo {
/**
* The display name of the user.
*
* @since 5.2.0
*/
displayName: string | null;
/**
* The email of the user.
*
* @since 5.2.0
*/
email: string | null;
/**
* The phone number normalized based on the E.164 standard (e.g. +16505550101) for the user.
*
* @since 5.2.0
*/
phoneNumber: string | null;
/**
* The profile photo URL of the user.
*
* @since 5.2.0
*/
photoUrl: string | null;
/**
* The provider used to authenticate the user.
*
* @since 5.2.0
*/
providerId: string;
/**
* The user's unique ID.
*
* @since 5.2.0
*/
uid: string;
}

/**
* @since 5.2.0
* @see https://firebase.google.com/docs/reference/js/auth.usermetadata
*/
export interface UserMetadata {
/**
* Time the user was created in milliseconds since the epoch.
*
* @since 5.2.0
* @example 1695130859034
*/
creationTime?: number;
/**
* Time the user last signed in in milliseconds since the epoch.
*
* @since 5.2.0
* @example 1695130859034
*/
lastSignInTime?: number;
}

/**
* @since 0.1.0
*/
Expand Down
32 changes: 32 additions & 0 deletions packages/authentication/src/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import type {
CustomParameters as FirebaseCustomParameters,
User as FirebaseUser,
UserCredential as FirebaseUserCredential,
UserInfo as FirebaseUserInfo,
UserMetadata as FirebaseUserMeatdata,
} from 'firebase/auth';
import {
EmailAuthProvider,
Expand Down Expand Up @@ -85,6 +87,8 @@ import type {
UpdateProfileOptions,
UseEmulatorOptions,
User,
UserInfo,
UserMetadata,
} from './definitions';
import { Persistence, ProviderId } from './definitions';

Expand Down Expand Up @@ -694,15 +698,43 @@ export class FirebaseAuthenticationWeb
email: user.email,
emailVerified: user.emailVerified,
isAnonymous: user.isAnonymous,
metadata: this.createUserMetadataResult(user.metadata),
phoneNumber: user.phoneNumber,
photoUrl: user.photoURL,
providerData: this.createUserProviderDataResult(user.providerData),
providerId: user.providerId,
tenantId: user.tenantId,
uid: user.uid,
};
return result;
}

private createUserMetadataResult(
metadata: FirebaseUserMeatdata,
): UserMetadata {
const result: UserMetadata = {};
if (metadata.creationTime) {
result.creationTime = Date.parse(metadata.creationTime);
}
if (metadata.lastSignInTime) {
result.lastSignInTime = Date.parse(metadata.lastSignInTime);
}
return result;
}

private createUserProviderDataResult(
providerData: FirebaseUserInfo[],
): UserInfo[] {
return providerData.map(data => ({
displayName: data.displayName,
email: data.email,
phoneNumber: data.phoneNumber,
photoUrl: data.photoURL,
providerId: data.providerId,
uid: data.uid,
}));
}

private createAdditionalUserInfoResult(
credential: FirebaseUserCredential | null,
): AdditionalUserInfo | null {
Expand Down