Я хотел бы добавить, что если вы получите расширение MoreLinq, теперь есть поддержка как гомогенных, так и гетерогенных левых соединений теперь
http://morelinq.github.io/2.8/ref /api/html/Overload_MoreLinq_MoreEnumerable_LeftJoin.htm
пример:
//Pretend a ClientCompany object and an Employee object both have a ClientCompanyID key on them
return DataContext.ClientCompany
.LeftJoin(DataContext.Employees, //Table being joined
company => company.ClientCompanyID, //First key
employee => employee.ClientCompanyID, //Second Key
company => new {company, employee = (Employee)null}, //Result selector when there isn't a match
(company, employee) => new { company, employee }); //Result selector when there is a match
EDIT:
В ретроспективе это может сработать, но оно преобразует IQueryable для IEnumerable, поскольку morelinq не преобразует запрос в SQL.
Вместо этого вы можете использовать GroupJoin, как описано здесь: https://stackoverflow.com/a/24273804/4251433
Это гарантирует, что он останется как IQueryable, если вам понадобится дальнейшие логические операции над ним позже.
Почему бы не отправить его из вашего интерфейса?
function resetPassword(emailAddress){
firebase.auth().sendPasswordResetEmail(emailAddress).then(function() {
console.log('email sent!');
}).catch(function(error) {
// An error happened.
});
}
Метод sendPasswordResetEmail()
- это метод из клиентского модуля auth
, и вы правы, у Admin-SDK его нет - или что-то сопоставимое. Большинство людей называют эту функцию из front-end ...
С учетом сказанного можно выполнить на бэкэнде ... но вам придется создавать свои собственные функции. Я уже делал это раньше, я вставлю часть своего кода из своих облачных функций, чтобы помочь вам ... если вы решите пойти по этой дороге. Я создаю свой JWT, добавляю его к URL-адресу, а затем использую NodeMailer для отправки им электронной почты с этой ссылкой ... когда они посещают эту ссылку ( страница сброса пароля ), они вводят свой новый пароль , а затем, когда они нажимают кнопку отправки, я вытаскиваю JWT из URL-адреса и передаю его моей второй облачной функции, которая проверяет ее, а затем сбрасывает свой пароль.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
var jwt = require('jsonwebtoken');
admin.initializeApp()
// Email functionality
const nodemailer = require('nodemailer');
// Pull the gmail login info out of the environment variables
const gmailEmail = functions.config().gmail.email;
const gmailPassword = functions.config().gmail.password;
// Configure the nodemailer with our gmail info
const mailTransport = nodemailer.createTransport({
service: 'gmail',
auth: {
user: gmailEmail,
pass: gmailPassword,
},
});
// Called from any login page, from the Forgot Password popup
// Accepts a user ID - finds that user in the database and gets the associated email
// Sends an email to that address containing a link to reset their password
exports.forgotPassword = functions.https.onRequest( (req, res) => {
// Make a query to the database to get the /userBasicInfo table...
admin.database().ref(`userBasicInfo`).once('value').then( dataSnapshot => {
let allUsers = dataSnapshot.val() ? dataSnapshot.val() : {};
let matchingUid = '';
let emailForUser = '';
// Loop over all of the users
Object.keys(allUsers).forEach( eachUid => {
// See if their email matches
allUsers[eachUid]['idFromSis'] = allUsers[eachUid]['idFromSis'] ? allUsers[eachUid]['idFromSis'] : '';
if (allUsers[eachUid]['idFromSis'].toUpperCase() === req.body.userIdToFind.toUpperCase()) {
// console.log(`Found matching user! Uid: ${eachUid} with idFromSis: ${allUsers[eachUid]['idFromSis']}... setting this as the matchingUid`);
matchingUid = eachUid;
emailForUser = allUsers[eachUid]['email'] ? allUsers[eachUid]['email'] : '';
}
})
// After loop, see if we found the matching user, and make sure they have an email address
if (matchingUid === '' || emailForUser == '') {
// Nothing found, send a failure response
res.send(false);
} else {
// Send an email to this email address containing the link to reset their password
// We need to generate a token for this user - expires in 1 hour = 60 minutes = 3600 seconds
jwt.sign({ uid: matchingUid }, functions.config().jwt.secret, { expiresIn: 60 * 60 }, (errorCreatingToken, tokenToSend) => {
if (errorCreatingToken) {
console.log('Error creating user token:');
console.log(errorCreatingToken);
let objToReplyWith = {
message: 'Error creating token for email. Please contact an adminstrator.'
}
res.json(objToReplyWith);
} else {
// Send token to user in email
// Initialize the mailOptions variable
const mailOptions = {
from: gmailEmail,
to: emailForUser,
};
// Building Email message.
mailOptions.subject = 'LMS Password Reset';
mailOptions.text = `
Dear ${req.body.userIdToFind.toUpperCase()},
The <system> at <company> has received a "Forgot Password" request for your account.
Please visit the following site to reset your password:
https://project.firebaseapp.com/home/reset-password-by-token/${tokenToSend}
If you have additional problems logging into LMS, please contact an adminstrator.
Sincerely,
<company>
`;
// Actually send the email, we need to reply with JSON
mailTransport.sendMail(mailOptions).then( () => {
// Successfully sent email
let objToReplyWith = {
message: 'An email has been sent to your email address containing a link to reset your password.'
}
res.json(objToReplyWith);
}).catch( err => {
// Failed to send email
console.log('There was an error while sending the email:');
console.log(err);
let objToReplyWith = {
message: 'Error sending password reset email. Please contact an adminstrator.'
}
res.json(objToReplyWith);
});
}
})
}
}).catch( err => {
console.log('Error finding all users in database:');
console.log(err);
res.send(false);
})
});
// Called when the unauthenticated user tries to reset their password from the reset-password-by-token page
// User received an email with a link to the reset-password-by-token/TOKEN-HERE page, with a valid token
// We need to validate that token, and if valid - reset the password
exports.forgotPasswordReset = functions.https.onRequest( (req, res) => {
// Look at the accessToken provided in the request, and have JWT verify whether it's valid or not
jwt.verify(req.body.accessToken, functions.config().jwt.secret, (errorDecodingToken, decodedToken) => {
if (errorDecodingToken) {
console.error('Error while verifying JWT token:');
console.log(error);
res.send(false);
}
// Token was valid, pull the UID out of the token for the user making this request
let requestorUid = decodedToken.uid;
admin.auth().updateUser(requestorUid, {
password: req.body.newPassword
}).then( userRecord => {
// Successfully updated password
let objToReplyWith = {
message: 'Successfully reset password'
}
res.json(objToReplyWith);
}).catch( error => {
console.log("Error updating password for user:");
console.log(error)
res.send(false);
});
});
});