@@ -150,8 +150,22 @@ Future<dynamic> _callExport({
150150 if (branchName != null ) 'branch_name' : branchName,
151151 'export_as_module' : exportAsModule,
152152 });
153+ return await _callEndpoint (
154+ client: client,
155+ token: token,
156+ url: Uri .https (endpoint.host, '${endpoint .path }/exportCode' ),
157+ body: body,
158+ );
159+ }
160+
161+ Future <dynamic > _callEndpoint ({
162+ required final http.Client client,
163+ required String token,
164+ required Uri url,
165+ required String body,
166+ }) async {
153167 final response = await client.post (
154- Uri . https (endpoint.host, '${ endpoint . path }/exportCode' ) ,
168+ url ,
155169 body: body,
156170 headers: {
157171 'Content-Type' : 'application/json' ,
@@ -265,3 +279,72 @@ Future _runFix({
265279 stderr.write ('Error running "dart fix": $e \n ' );
266280 }
267281}
282+
283+ Future firebaseDeploy ({
284+ required String token,
285+ required String projectId,
286+ required String destinationPath,
287+ String endpoint = kDefaultEndpoint,
288+ }) async {
289+ final endpointUrl = Uri .parse (endpoint);
290+ final body = jsonEncode ({
291+ 'project' : {
292+ 'path' : 'projects/$projectId ' ,
293+ },
294+ 'token' : token,
295+ });
296+ final result = await _callEndpoint (
297+ client: http.Client (),
298+ token: token,
299+ url: Uri .https (
300+ endpointUrl.host, '${endpointUrl .path }/exportFirebaseDeployCode' ),
301+ body: body,
302+ );
303+
304+ // Download actual code
305+ final projectZipBytes = base64Decode (result['firebase_zip' ]);
306+ final firebaseProjectId = result['firebase_project_id' ];
307+ final projectFolder = ZipDecoder ().decodeBytes (projectZipBytes);
308+ extractArchiveToCurrentDirectory (projectFolder, destinationPath);
309+ final firebaseDir = '$destinationPath /firebase' ;
310+
311+ // Install required modules for deployment.
312+ await Process .run (
313+ 'npm' ,
314+ ['install' ],
315+ workingDirectory: '$firebaseDir /functions' ,
316+ runInShell: true ,
317+ stdoutEncoding: utf8,
318+ stderrEncoding: utf8,
319+ );
320+ final directoriesResult = await Process .run (
321+ 'ls' ,
322+ [],
323+ workingDirectory: firebaseDir,
324+ runInShell: true ,
325+ stdoutEncoding: utf8,
326+ stderrEncoding: utf8,
327+ );
328+
329+ // This directory only exists if there were custom cloud functions.
330+ if (directoriesResult.stdout.contains ('custom_cloud_functions' )) {
331+ await Process .run (
332+ 'npm' ,
333+ ['install' ],
334+ workingDirectory: '$firebaseDir /custom_cloud_functions' ,
335+ runInShell: true ,
336+ stdoutEncoding: utf8,
337+ stderrEncoding: utf8,
338+ );
339+ }
340+
341+ final deployProcess = await Process .start (
342+ 'firebase' ,
343+ ['deploy' , '--project' , firebaseProjectId],
344+ workingDirectory: firebaseDir,
345+ runInShell: true ,
346+ );
347+ // There may be a need for the user to interactively provide inputs.
348+ deployProcess.stdout.transform (utf8.decoder).forEach (print);
349+ deployProcess.stdin.addStream (stdin);
350+ }
0 commit comments